第五课 工厂方法模式

来源:互联网 发布:windows截图保存路径 编辑:程序博客网 时间:2024/04/30 02:35
 

第五课 工厂方法模式

 

    这个模式用法通过例子很容易学会,但是我一直没能体会到他存在的意义,他能提供的好处。所以在群里讨论了下,也没有搞明白。最终,无意中在Java编程思想中看到了一个工厂方法的应用,突然大彻大悟(呵呵),谁说工厂方法只能零散着调用,可以结合别的模式一起使用吗。呵呵,下面进入正题。

    首先回想一下简单工厂的优缺点。

    优点:

对产品对象能够很好的实现开闭原则。能够将复杂的获取哪个对象逻辑判断封装到具体的工厂类中,具体判断不对客户端(调用程序)开发,达到了逻辑封装的效果。

       缺点:

              如果新增新的产品,除了要实现新的产品外,还必须要修改工厂方法。

 

       上一讲我说了,正由于这个缺点的存在,诞生了工厂方法模式。

       工厂方法的思想是,对工厂类进行进一步的抽象,将他的抽象和实现也进行分离。从而实现开闭原则。这样根据依赖倒转原则,我们将处理的重点放在抽象上,不去依赖具体的实现。这里思路与产品一样。将工厂方法的核心抽象出一个工厂方法的基类(或接口)。由具体的工厂实现类来依照我们的处理思路去实现工厂方法。下面看实例代码。

Java与模式的例子很空洞,这里引用大话设计模式的例子)

C#:

 

1.        using System;

2.        using System.Collections.Generic;

3.        using System.Text;

4.         

5.        namespace 工厂方法_计算器

6.        {

7.         

8.            /// <summary>

9.            /// 运算类

10.         /// </summary>

11.         class Operation

12.         {

13.             private double _numberA = 0;

14.             private double _numberB = 0;

15.      

16.             public double NumberA

17.             {

18.                 get { return _numberA; }

19.                 set { _numberA = value; }

20.             }

21.      

22.             public double NumberB

23.             {

24.                 get { return _numberB; }

25.                 set { _numberB = value; }

26.             }

27.      

28.             /// <summary>

29.             /// 得到运算结果

30.             /// </summary>

31.             /// <returns></returns>

32.             public virtual double GetResult()

33.             {

34.                 double result = 0;

35.                 return result;

36.             }

37.         }

38.      

39.         /// <summary>

40.         /// 加法类

41.         /// </summary>

42.         class OperationAdd : Operation

43.         {

44.             public override double GetResult()

45.             {

46.                 double result = 0;

47.                 result = NumberA + NumberB;

48.                 return result;

49.             }

50.         }

51.      

52.         /// <summary>

53.         /// 减法类

54.         /// </summary>

55.         class OperationSub : Operation

56.         {

57.             public override double GetResult()

58.             {

59.                 double result = 0;

60.                 result = NumberA - NumberB;

61.                 return result;

62.             }

63.         }

64.         /// <summary>

65.         /// 乘法类

66.         /// </summary>

67.         class OperationMul : Operation

68.         {

69.             public override double GetResult()

70.             {

71.                 double result = 0;

72.                 result = NumberA * NumberB;

73.                 return result;

74.             }

75.         }

76.         /// <summary>

77.         /// 除法类

78.         /// </summary>

79.         class OperationDiv : Operation

80.         {

81.             public override double GetResult()

82.             {

83.                 double result = 0;

84.                 if (NumberB == 0)

85.                     throw new Exception("除数不能为0");

86.                 result = NumberA / NumberB;

87.                 return result;

88.             }

89.         }

90.      

91.         /// <summary>

92.         /// 工厂方法

93.         /// </summary>

94.         interface IFactory

95.         {

96.             Operation CreateOperation();

97.         }

98.      

99.         /// <summary>

100.      /// 专门负责生产“+”的工厂

101.      /// </summary>

102.      class AddFactory : IFactory

103.      {

104.          public Operation CreateOperation()

105.          {

106.              return new OperationAdd();

107.          }

108.      }

109.   

110.      /// <summary>

111.      /// 专门负责生产“-”的工厂

112.      /// </summary>

113.      class SubFactory : IFactory

114.      {

115.          public Operation CreateOperation()

116.          {

117.              return new OperationSub();

118.          }

119.      }

120.   

121.      /// <summary>

122.      /// 专门负责生产“*”的工厂

123.      /// </summary>

124.      class MulFactory : IFactory

125.      {

126.          public Operation CreateOperation()

127.          {

128.              return new OperationMul();

129.          }

130.      }

131.   

132.      /// <summary>

133.      /// 专门负责生产“/”的工厂

134.      /// </summary>

135.      class DivFactory : IFactory

136.      {

137.          public Operation CreateOperation()

138.          {

139.              return new OperationDiv();

140.          }

141.      }

142.   

143.      class DoOperation

144.      {

145.          public static double DoComboOperation(IFactory fac,double a,double b)

146.          {

147.              Operation op = fac.CreateOperation();

148.              op.NumberA = a;

149.              op.NumberB = b;

150.              return op.GetResult();

151.          }

152.      }

153.  }

154.   

 

里面除去DoOperation是我加的外,全部原版代码。可以说是工厂方法模式的标准实现方法了。下面咱们分析一下。首先在产品这部分,处理思路和简单工厂是一样的,这里不再提了。工厂这里注意一下。他也采用了类似产品的做法,抽象了一个接口IFactory 然后在观察那几个具体的实现的工厂类, AddFactory 等,这是就会发现,每一个产品对象都有自己的工厂。其实我原来就在这里有疑问,这样确实避免了简单工厂的缺点,新增产品的时候只需要新增生产这个产品的工厂,不需要修改工厂接口。但是感觉在使用的时候没有什么方便。所以一直在怀疑他的存在价值。现在我多少明白了一点。看我新加的DoOperation 类。里面有DoComboOperation方法,参数是IFactory和两个运算数。现在来看了。我如果要执行加法,我传入一个加法工厂和两个值,即可,我如果执行减法,我传入减法工厂和两个值。这样直接将产品给完全隔离了,对外只有工厂接口。能感觉到点意思了吧。想象下,如果我这里又复杂的处理逻辑呢,并且加减乘除都能够操作。(Java思想里面例子是下棋,不同的棋走不同的步数)这个方法是模板模式。模板模式和工厂方法结合的时候,就能体现工厂方法的意义了。并且工厂方法通过DoOperation 这种方式甚至可以完全隔离产品。

可能你还很晕哦,但是先记住这种用法,到实践中去体会吧。

 

工厂方法就到这里,下次我们来看抽象工厂模式。

 

作者:王文斌

转载请注明出处哦

 

 

原创粉丝点击