简单工厂模式
看了下大话设计模式,结合网上的各种觉得自己能够理解的好的资料整理一下,以备后用。
1 基础概念:(转)
OCP(开闭原则,Open-Closed Principle):一个软件的实体应当对扩展开放,对修改关闭。我的理解是,对于一个已有的软件,如果需要扩展,应当在不需修改已有代码的基础上进行。
DIP(依赖倒转原则,Dependence Inversion Principle):要针对接口编程,不要针对实现编程。我的理解是,对于不同层次的编程,高层次暴露给低层次的应当只是接口,而不是它的具 体类。
LoD(迪米特法则,Law of Demeter):只与你直接的朋友通信,而避免和陌生人通信。众所周知类(或模块)之间的通信越少,耦合度就越低,从而更有利于我们对软件的宏观管理。
2 简单工厂模式概念。
简单工厂模式的实质是由一个工厂类根据传入的参数,动态决定应该创建哪一个产品类(这些产品类继承自一个父类或接口)的实例。
该模式中包含的角色及其职责
工厂(Creator)角色
简单工厂模式的核心,它负责实现创建所有实例的内部逻辑。工厂类可以被外界直接调用,创建所需的产品对象。
抽象产品(Product)角色
简单工厂模式所创建的所有对象的父类,它负责描述所有实例所共有的公共接口。
具体产品(Concrete Product)角色
是简单工厂模式的创建目标,所有创建的对象都是充当这个角色的某个具体类的实例。
3 实例(大话模式代码,计算器的编写)
(1)业务的封装,让业务逻辑跟界面逻辑分开,达到易扩展和维护。
运算类Operation
1 public class Operation 2 { 3 public static double GetResult(double num1,double num2,string op) 4 { 5 double res = 0d; 6 switch(op) 7 { 8 case "+": 9 res = num1+ num2; 10 break; 11 12 case "-": 13 res = num1 - num2; 14 break; 15 16 case "*": 17 res = num1* num2; 18 break; 19 20 case "/": 21 res = num1/ num2; 22 break; 23 } 24 return res; 25 } 26 } 27 28 客户端代码: 29 class Program 30 { 31 32 static void Main(string[] args) 33 { 34 try 35 { 36 Console.Write("input num1:"); 37 string strNum1 = Console.ReadLine(); 38 Console.Write("input Operation:"); 39 string op = Console.ReadLine(); 40 Console.Write("input num2:"); 41 string strNum2 = Console.ReadLine(); 42 string result = ""; 43 result = Convert.ToString(Operation.GetResult(Convert.ToDouble(strNum1),Convert.ToDouble(strNum2),op)); 44 Console.WriteLine("the result is :"+result); 45 Console.ReadLine(); 46 47 } 48 catch(Exception ex) 49 { 50 Console.WriteLine("wrone input"+ex.Message); 51 } 52 } 53 }
此时虽然业务逻辑跟界面逻辑分开了,但是假如我要添加一个运算方法如开根号,我必须要重新修改Operation类,这样做的话就把原来的运算都得来参与编译,容易出错。
从写Operation类
//Operation类(上面提到的抽象角色) public class Operation { private double _num1 = 0; private double _num2 = 0; public double Number1 { get {return _num1;} set { _num1 = value;} } public double Number2 { get {return _num2;} set { _num2 = value;} } public virtual double GetResult(){ double result = 0; return result; } } //加减乘除类(上面提到的具体产品角色) class OperationAdd : Operation { public override double GetResult() { double res = 0; res = Number1 + Number2; return res; } } //加减乘除类 class OperationAdd : Operation { public override double GetResult() { double res = 0; res = Number1 - Number2; return res; } } //其他类似
此时加减乘除写成了运算类的子类,继承它后重写GetResult()方法,这样修改任何一个运算就不用提供其他运算的代码了,这时候的问题如何让计算器知道我希望用的是哪一个算法呢,简单的工厂模式就派上用场了,用一个单独的类来创造实例的过程就是工厂。
//(工厂角色)
public class OperationFactory { public static Operation createOperate(string operate) { Operation op = null; switch(operate) { case "+": op = new OperationAdd(); break; case "-": op = new OperationSub(); break; case "*": op = new OperationMul(); break; case "/": op = new OperationDiv(); break; } return op; } } //客户端代码 class program { static void Main(string[] args) { Operation oper; oper = OperationFactory.createOperate("+"); oper.Number1 = 1; oper.Number2 = 3; double res = oper.GetResult(); Console.WriteLine("the result is :"+res); Console.ReadLine(); } }
现在只要输入运算符就能实例化合适的对象,返回计算结果。这时候要增加各种运算只需要增加对应的运算子类并且在工厂类增加分支即可。