设计模式——工厂模式

  工厂模式——定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类。

  工厂模式和简单工厂模式同属于工厂类型的模式,都是以一个工厂生产对象为目标,降低耦合。要说区别,就是在创建产品对象的时候的方式不同。简单工厂模式工厂里面还是存在一些耦合的,当需要创建新的产品时,还是需要去修改这个工厂类的。而工厂模式由子类去创建产品,不需要改工厂,只需添加一个工厂,再一次的降低的耦合性。相应的,也带来了代码量的增加。

  下面还是以计算器为例子,展示下工厂模式的应用。

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 }
Operation.cs

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 }
OperationProduct.cs

3.IFactory接口,这个接口定义了创建工厂的方法,然后可以由子类去实现工厂的创建

/// <summary>
/// 抽象接口
/// </summary>
public interface IFactory
{
    /// <summary>
    /// 创建具体对象的方法
    /// </summary>
    /// <returns></returns>
    Operation CreateOperation();
}
}
IFactory.cs

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 }
OperatIonFactory.cs

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 }
Program.cs

  简单工厂的最大优点就是在于工厂类中包含了必要的逻辑判断,根据客户端的选择条件动态实例化相关的类,对于客户端来说,去除了于具体产品的依赖,但是它违背了开发—封闭原则。

  工厂模式实现时,客户端需要决定实例化哪一个工厂来实现运算类,把选择判断的任务从工厂类移交给了客户端。

  鱼和熊掌不可兼得,工厂模式和简单工厂模式各有好处,不能说谁好谁坏,要根据具体的项目进行选择。

                                                          以上内容部分参考程杰的《大话设计模式》一书

原文地址:https://www.cnblogs.com/Smilodon/p/3098359.html