上一篇文章写了如何使用RabbitMQ做个简单的发送邮件项目,然后评论也是比较多,也是准备去学习一下如何确保RabbitMQ的消息可靠性,但是由于时间原因,先来说说设计模式中的简单工厂模式吧! 在了解简单工厂模式之前,我们要知道C#是一款面向对象的高级程序语言。它有3大特性,封装、继承、多态。
工厂模式(Factory Pattern)是一种常用的设计模式,属于创建型模式,它提供了一种创建对象的最佳方式。在工厂模式中,我们创建对象时不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象。 工厂模式的核心是定义一个创建产品对象的工厂接口,将实际创建工作推迟到子类当中。这样客户端可以无需指定具体产品的类,只需通过工厂类即可得到所需的产品对象。
工厂模式主要分为三种类型:简单工厂模式(Simple Factory Pattern)、工厂方法模式(Factory Method Pattern)和抽象工厂模式(Abstract Factory Pattern)。 本文主要讲解简单工厂模式(Simple Factory Pattern)。
下面使用C#控制台程序去写一个简易的计算器,实现加减乘除。如果我没学过设计模式,我会这么写:
static void Main(string[] args) { Console.WriteLine("请输入数字A:"); string A = Console.ReadLine(); Console.WriteLine("请选择运算符号:(+、-、*、/):"); string op = Console.ReadLine(); Console.WriteLine("请输入数字B:"); string B = Console.ReadLine(); string result = ""; switch (op) { case "+": result = Convert.ToString(Convert.ToDouble(A) + Convert.ToDouble(B)); break; case "-": result = Convert.ToString(Convert.ToDouble(A) - Convert.ToDouble(B)); break; case "*": result = Convert.ToString(Convert.ToDouble(A) * Convert.ToDouble(B)); break; case "/": result = Convert.ToString(Convert.ToDouble(A) / Convert.ToDouble(B)); break; default: Console.WriteLine("输入的运算符号有误!"); break; } Console.WriteLine("结果:" + result); }
static void Main(string[] args)
{
Console.WriteLine("请输入数字A:");
string A = Console.ReadLine();
Console.WriteLine("请选择运算符号:(+、-、*、/):");
string op = Console.ReadLine();
Console.WriteLine("请输入数字B:");
string B = Console.ReadLine();
string result = "";
switch (op)
case "+":
result = Convert.ToString(Convert.ToDouble(A) + Convert.ToDouble(B));
break;
case "-":
result = Convert.ToString(Convert.ToDouble(A) - Convert.ToDouble(B));
case "*":
result = Convert.ToString(Convert.ToDouble(A) * Convert.ToDouble(B));
case "/":
result = Convert.ToString(Convert.ToDouble(A) / Convert.ToDouble(B));
default:
Console.WriteLine("输入的运算符号有误!");
}
Console.WriteLine("结果:" + result);
上述代码乍一看没问题,实则隐藏了很多陷阱,比如:
我们用面向对象的思想进行优化,主要体现在:可维护、可复用、可扩展、灵活性几个方面。通过封装、继承、多态来降低程序的耦合度。
我们可以将运算逻辑封装成一个方法去实现,让主方法减轻负担。封装后: Operation类
Operation
public class Operation{ public static double GetResult(double num1, double num2, string op) { double result = 0d; switch (op) { case "+": result = num1 + num2; break; case "-": result = num1 - num2; break; case "*": result = num1 * num2; break; case "/": result = num1 / num2; break; } return result; }}
public class Operation
public static double GetResult(double num1, double num2, string op)
double result = 0d;
result = num1 + num2;
result = num1 - num2;
result = num1 * num2;
result = num1 / num2;
return result;
Main方法
Main
static void Main(string[] args){ try { Console.WriteLine("请输入数字A:"); string strNumA = Console.ReadLine(); Console.WriteLine("请选择运算符号:(+、-、*、/):"); string op = Console.ReadLine(); Console.WriteLine("请输入数字B:"); string strNumB = Console.ReadLine(); string result = ""; result = Convert.ToString(Operation.GetResult(Convert.ToDouble(strNumA), Convert.ToDouble(strNumB), op)); Console.WriteLine("结果:" + result); } catch (Exception e) { Console.WriteLine("发生异常:" + e.Message); }}
try
string strNumA = Console.ReadLine();
string strNumB = Console.ReadLine();
result = Convert.ToString(Operation.GetResult(Convert.ToDouble(strNumA), Convert.ToDouble(strNumB), op));
catch (Exception e)
Console.WriteLine("发生异常:" + e.Message);
当我们完成封装后开始思考一个问题,如果后面有新的需求,需要增加一个开根运行,应该如何去修改?如果是我,我会在switch里面加一个分支,但是这样耦合度太高。我明明只需要去开根,但是却要让加减乘除参与进来,所以我们应该将加减乘除运算分离出来。 优化耦合度:
public class Operation{ private double _num1; private double _num2; public double Num1 { get => _num1; set => _num1 = value; } public double Num2 { get => _num2; set => _num2 = value; } public virtual double GetResult() { return 0; }}//加法类public class AddOperation : Operation{ public override double GetResult() { return Num1 + Num2; }}//减法类public class SubtractOperation : Operation{ public override double GetResult() { return Num1 - Num2; }}//乘法类public class MultiplyOperation : Operation{ public override double GetResult() { return Num1 * Num2; }}//除法类public class DivideOperation : Operation{ public override double GetResult() { if (Num2 == 0) throw new DivideByZeroException("除数不能为0"); return Num1 / Num2; }}
private double _num1;
private double _num2;
public double Num1 { get => _num1; set => _num1 = value; }
public double Num2 { get => _num2; set => _num2 = value; }
public virtual double GetResult()
return 0;
//加法类
public class AddOperation : Operation
public override double GetResult()
return Num1 + Num2;
//减法类
public class SubtractOperation : Operation
return Num1 - Num2;
//乘法类
public class MultiplyOperation : Operation
return Num1 * Num2;
//除法类
public class DivideOperation : Operation
if (Num2 == 0)
throw new DivideByZeroException("除数不能为0");
return Num1 / Num2;
我创建了Operation基类,并定义了2个成员变量_num1和_num2,同时定义了一个GetResult虚方法。同时分别创建了加减乘除子类去重写GetResult方法来降级耦合度。
_num1
_num2
GetResult
我们需要通过简单工厂模式,来让程序知道该实例化谁。需要来创建一个工厂类:
public class OperationFactory{ public static Operation CreateOperation(string operation) { switch (operation) { case "+": return new AddOperation(); case "-": return new SubtractOperation(); case "*": return new MultiplyOperation(); case "/": return new DivideOperation(); default: return null; } }}
public class OperationFactory
public static Operation CreateOperation(string operation)
switch (operation)
return new AddOperation();
return new SubtractOperation();
return new MultiplyOperation();
return new DivideOperation();
return null;
创建了工厂类有什么好处呢,好处就是,只需要输入运算符号,工厂就能自己实例化出合适的对象,通过多态,返回父类的方法实现了计算器的计算结果。 Main方法 通过简单工厂模式,让我们在计算加减乘除的时候只需要去增加对应的子类就行了,下面的代码进行加法运行时,通过传入+号让工厂去帮我们实例化子类。
static void Main(string[] args) { try { // 简单工厂模式 var oper = OperationFactory.CreateOperation("+"); oper.Num1 = 10; oper.Num2 = 5; Console.WriteLine(oper.GetResult()); } catch (Exception e) { Console.WriteLine("发生异常:" + e.Message); }}
// 简单工厂模式
var oper = OperationFactory.CreateOperation("+");
oper.Num1 = 10;
oper.Num2 = 5;
Console.WriteLine(oper.GetResult());
讲完简单工厂模式后,简简单单复现一下类图:
原文链接:https://www.cnblogs.com/ZYPLJ/p/18306505
本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728