工厂模式——定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类。
工厂模式和简单工厂模式同属于工厂类型的模式,都是以一个工厂生产对象为目标,降低耦合。要说区别,就是在创建产品对象的时候的方式不同。简单工厂模式工厂里面还是存在一些耦合的,当需要创建新的产品时,还是需要去修改这个工厂类的。而工厂模式由子类去创建产品,不需要改工厂,只需添加一个工厂,再一次的降低的耦合性。相应的,也带来了代码量的增加。
下面还是以计算器为例子,展示下工厂模式的应用。
1.Operation类,于简单工厂无异,还是作为一个具体实现类的父类
1 /// <summary> 2 /// 这是一个父类,主要作用是获取参数值, 3 /// 定义一个抽象方法,给子类进行重写 4 /// </summary> 5 public class Operation 6 { 7 /// <summary> 8 /// 用于运算的参数A 9 /// </summary> 10 public double NumberA { get; set; } 11 12 public Operation() 13 { 14 NumberB = 0; 15 } 16 17 /// <summary> 18 /// 用于运算的参数B 19 /// </summary> 20 public double NumberB { get; set; } 21 22 /// <summary> 23 ///这是一个抽象类,给子类进行重写, 24 ///进行具体运算符的运算 25 /// </summary> 26 /// <returns>运算结果</returns> 27 public virtual double GetResult() 28 { 29 const double result = 0; 30 return result; 31 } 32 }
2.OperationProduct类,具体的实现类,这些类实现了具体的计算
1 /// <summary> 2 /// 加法运算实现类 3 /// </summary> 4 public class OperationAdd : Operation 5 { 6 /// <summary> 7 /// 加法运算实现方法 8 /// </summary> 9 /// <returns>运算结果</returns> 10 public override double GetResult() 11 { 12 double result = NumberA + NumberB; 13 return result; 14 } 15 } 16 /// <summary> 17 /// 减法运算实现类 18 /// </summary> 19 public class OperationSub : Operation 20 { 21 /// <summary> 22 /// 减法运算实现方法 23 /// </summary> 24 /// <returns>运算结果</returns> 25 public override double GetResult() 26 { 27 double result = NumberA + NumberB; 28 return result; 29 } 30 } 31 /// <summary> 32 /// 乘法运算实现类 33 /// </summary> 34 public class OperationMul : Operation 35 { 36 /// <summary> 37 /// 乘法运算实现方法 38 /// </summary> 39 /// <returns>运算结果</returns> 40 public override double GetResult() 41 { 42 double result = NumberA * NumberB; 43 return result; 44 } 45 } 46 /// <summary> 47 /// 除法运算实现类 48 /// </summary> 49 public class OperationDiv : Operation 50 { 51 /// <summary> 52 /// 除法运算实现方法 53 /// </summary> 54 /// <returns>运算结果</returns> 55 public override double GetResult() 56 { 57 double result; 58 const double epsilon = 0; 59 if (Math.Abs(NumberB - 0) > epsilon) 60 { 61 result = NumberA / NumberB; 62 } 63 else 64 { 65 throw new Exception("除数不能为0"); 66 } 67 return result; 68 } 69 }
3.IFactory接口,这个接口定义了创建工厂的方法,然后可以由子类去实现工厂的创建
/// <summary> /// 抽象接口 /// </summary> public interface IFactory { /// <summary> /// 创建具体对象的方法 /// </summary> /// <returns></returns> Operation CreateOperation(); } }
4.OperationFactory,这里面都是一些工厂子类,每个子类对应一个具体实现类,来实现具体运算对象的创建
1 /// <summary> 2 /// 加法对象的创建 3 /// </summary> 4 public class AddFactory:IFactory 5 { 6 public Operation CreateOperation() 7 { 8 return new OperationAdd(); 9 } 10 } 11 12 /// <summary> 13 /// 减法对象的创建 14 /// </summary> 15 public class SubFactory:IFactory 16 { 17 public Operation CreateOperation() 18 { 19 return new OperationSub(); 20 } 21 } 22 23 /// <summary> 24 /// 乘法对象的创建 25 /// </summary> 26 public class MulFactory:IFactory 27 { 28 public Operation CreateOperation() 29 { 30 return new OperationMul(); 31 } 32 } 33 34 /// <summary> 35 /// 除法对象的创建 36 /// </summary> 37 public class DivFactory:IFactory 38 { 39 public Operation CreateOperation() 40 { 41 return new OperationDiv(); 42 } 43 }
5.客户端代码
1 static void Main(string[] args) 2 { 3 //创建加法工厂对象 4 var operFactory = new AddFactory(); 5 //让工厂去创建具体的实现加法计算的对象 6 Operation operation = operFactory.CreateOperation(); 7 //进行赋值 8 operation.NumberA = 1; 9 operation.NumberB = 2; 10 //得到结果 11 double result = operation.GetResult(); 12 }
简单工厂的最大优点就是在于工厂类中包含了必要的逻辑判断,根据客户端的选择条件动态实例化相关的类,对于客户端来说,去除了于具体产品的依赖,但是它违背了开发—封闭原则。
工厂模式实现时,客户端需要决定实例化哪一个工厂来实现运算类,把选择判断的任务从工厂类移交给了客户端。
鱼和熊掌不可兼得,工厂模式和简单工厂模式各有好处,不能说谁好谁坏,要根据具体的项目进行选择。
以上内容部分参考程杰的《大话设计模式》一书