目前正在看《大话设计模式》,写此系列的文章记录下学习的经过。
简单工厂模式
先看如下代码,使用面向对象的原理实现计算器功能
Operation运算类
1 public class Operation 2 { 3 private double numberA = 0; 4 private double numberB = 0; 5 6 public double NumberA 7 { 8 get { return numberA; } 9 set { numberA = value; } 10 } 11 12 public double NumberB 13 { 14 get { return numberB; } 15 set { numberB = value; } 16 } 17 18 public virtual double GetResult() 19 { 20 double result = 0; 21 return result; 22 } 23 }
加减乘除类
1 public class OperationAdd:Operation 2 { 3 public override double GetResult() 4 { 5 double result = NumberA + NumberB; 6 return result; 7 } 8 } 9 10 public class OperationSub : Operation 11 { 12 public override double GetResult() 13 { 14 double result = NumberA - NumberB; 15 return result; 16 } 17 } 18 19 public class OperationMul : Operation 20 { 21 public override double GetResult() 22 { 23 double result = NumberA * NumberB; 24 return result; 25 } 26 } 27 28 public class OperationDiv : Operation 29 { 30 public override double GetResult() 31 { 32 if (NumberB == 0) 33 { 34 throw new Exception("除数不能为零!"); 35 } 36 double result = NumberA / NumberB; 37 return result; 38 } 39 }
有了运算类和加减乘除类之后,现在的问题就是如何去实例化对象的问题,也就是,到底要实力话谁,将来会不会增加实例化的对象,比如增加开跟运算,这时应该考虑用一个单独的类来做这个创造实例的过程
这就是工厂。
简单运算工厂类
1 public class OperationFactory 2 { 3 public static Operation CreateOperae(string operate) 4 { 5 Operation oper = null; 6 switch (operate) 7 { 8 case "+": 9 oper = new OperationAdd(); 10 break; 11 case "-": 12 oper = new OperationSub(); 13 break; 14 case "*": 15 oper = new OperationMul(); 16 break; 17 case "/": 18 oper = new OperationDiv(); 19 break; 20 } 21 return oper; 22 } 23 }
客户端代码
Operation oper; oper = OperationFactory.CreateOperae("+"); oper.NumberA = 2; oper.NumberB = 5; double result = oper.GetResult();
简单工厂模式:是通过专门定义一个类来负责创建其它类的实例,被创建的实例通常具有共同的父类。
在这里,我们根据不同的需求,通过OperationFactory类来负责创建其他类的实例。
优缺点
优点:工厂类是整个模式的关键,包含了逻辑判断,根据客户端信息,决定应该实例化那个具体的类,
客户端不用管这些对象是如何创建以及如何组织的,仅仅需要操作工厂类,明确了各自的职责和权利,
有利于整个软件体系结构的优化
缺点:由于工厂类集中了所有实例的创建逻辑,违反了高内聚责任分配原则,将全部创建逻辑集中到了一个工厂类中;
它所能创建的类只能是事先考虑到的,如果需要添加新的类,则就需要改变工厂类了。
使用场景:工厂类负责创建的对象比较少;
客户只知道传入工厂类的参数,对于如何创建对象(逻辑)不关心;
由于简单工厂很容易违反高内聚责任分配原则,因此一般只在很简单的情况下应用。