什么是简单工厂模式

什么是简单工厂模式

工厂模式有一种非常形象的描述,建立对象的类就如一个工厂,而需要被建立的对象就是一个个产品;在工厂中加工产品,使用产品的人,不用在乎产品是如何生产出来的。从软件开发的角度来说,这样就有效的降低了模块之间的耦合。

简单工厂的作用是实例化对象,而不需要客户了解这个对象属于哪个具体的子类。简单工厂实例化的类具有相同的接口或者基类,在子类比较固定并不需要扩展时,可以使用简单工厂。如数据库生产工厂就是简单工厂的一个应用

采用简单工厂的优点是可以使用户根据参数获得对应的类实例,避免了直接实例化类,降低了耦合性;缺点是可实例化的类型在编译期间已经被确定,如果增加新类 型,则需要修改工厂,不符合OCP(开闭原则)的原则。简单工厂需要知道所有要生成的类型,当子类过多或者子类层次过多时不适合使用。

简单工厂模式实现

下面考虑《大话设计模式》中的一个例子:

题目:用任意一种面向对象语言实现一个计算器控制台程序。要求输入两个数和运算符号,得到结果。

题目分析:

程序应该做到:(1)可维护;(2)可复用;(3)可扩展;(4)灵活性好。
可维护:就是说代码一处更改,不能产生连锁反应,不能影响其他地方。
可复用:尽量减少重复性代码。
可扩展:如果要扩展新的功能、新的业务,则只需要增加新的类就好了,不对已有的类和逻辑产生影响。插拔式的应用。

面向对象要点:
面向对象三大特性:封装、继承、多态。
通过封装、继承、多态把程序耦合降低。
业务逻辑和界面逻辑分开。

类的结构图:


代码实现:

1. 首先,搞清楚业务中容易发生变化的部分。在本应用中,要求计算两个数的运算结果,那么要进行什么样的运算,这就是一个容易发生变化的部分。例如,我们现在只想实现加减乘除运算,后期又想增加开根或者求余运算。那么如何应对这种需求带来的变化。在程序设计的时候就应该考虑到程序的可维护性、可扩展性、代码的可复用性、灵活性等等。
 
2. 例如现在这个运算器只有加减乘除四种运算。首先建一个Operation类,这个类是各种具体运算类(加减乘除)的父类,主要是接受用户输入的数值。该类如下:


 
 
  1. class Operation():
  2. def __init__(self,NumberA=0,NumberB=0):
  3. self.NumberA = NumberA
  4. self.NumberB = NumberB
  5. def GetResult(self):
  6. pass

3. 然后是具体的运算类:Add、Sub、Mul、Div。他们都继承了Operation类,并且重写了getResult()方法。这样就可以用多态性降低不同业务逻辑的耦合度,修改任何一种运算类都不会影响其他的运算类。具体类的代码如下:


 
 
  1. class AddOp(Operation):
  2. def GetResult(self):
  3. return self.NumberB + self.NumberA
  4. class MinusOp(Operation):
  5. def GetResult(self):
  6. return self.NumberA - self.NumberB
  7. class MultiOp(Operation):
  8. def GetResult(self):
  9. return self.NumberA * self.NumberB
  10. class DivideOp(Operation):
  11. def GetResult(self):
  12. try:
  13. return 1.0* self.NumberA / self.NumberB
  14. except ZeroDivisionError:
  15. raise

4.  那么如何让计算器知道我是要用哪一种运算呢?也就是说到底要实例化哪一个具体的运算类,Add?Sub?Mul?Div?这时就应该考虑用 一个单独的类来做这个创造具体实例的过程,这个类就是工厂类。如下:


 
 
  1. class OperationFatory():
  2. def ChooseOperation(self,op):
  3. if op == '+':
  4. return AddOp()
  5. if op == '-':
  6. return MinusOp()
  7. if op == '*':
  8. return MultiOp()
  9. if op == '/':
  10. return DivideOp()
5. 这样,用户只要输入运算符,工厂类就可以创建合适的实例,通过多态性,即返回给父类的方式实现运算结果。客户端代码如下:


 
 
  1. if __name__ == '__main__':
  2. ch = ''
  3. while not ch== 'q':
  4. NumberA = eval(raw_input( 'Please input number1: '))
  5. op = str(raw_input( 'Please input the operation: '))
  6. NumberB = eval(raw_input( 'Please input number2: '))
  7. OPFactory = OperationFatory()
  8. OPType = OPFactory.ChooseOperation(op)
  9. OPType.NumberA = NumberA
  10. OPType.NumberB = NumberB
  11. print 'The result is:',OPType.GetResult()
  12. print '\n#-- input q to exit any key to continue'
  13. try:
  14. ch = str(raw_input())
  15. except:
  16. ch = ''

完整版代码如下:


 
 
  1. # -*-coding:UTF-8-*-
  2. from abc import ABCMeta,abstractmethod
  3. class Operation():
  4. def __init__(self,NumberA=0,NumberB=0):
  5. self.NumberA = NumberA
  6. self.NumberB = NumberB
  7. def GetResult(self):
  8. pass
  9. class AddOp(Operation):
  10. def GetResult(self):
  11. return self.NumberB + self.NumberA
  12. class MinusOp(Operation):
  13. def GetResult(self):
  14. return self.NumberA - self.NumberB
  15. class MultiOp(Operation):
  16. def GetResult(self):
  17. return self.NumberA * self.NumberB
  18. class DivideOp(Operation):
  19. def GetResult(self):
  20. try:
  21. return 1.0* self.NumberA / self.NumberB
  22. except ZeroDivisionError:
  23. raise
  24. class OperationFatory():
  25. def ChooseOperation(self,op):
  26. if op == '+':
  27. return AddOp()
  28. if op == '-':
  29. return MinusOp()
  30. if op == '*':
  31. return MultiOp()
  32. if op == '/':
  33. return DivideOp()
  34. if __name_ _ == '__main__':
  35. ch = ''
  36. while not ch== 'q':
  37. NumberA = eval(raw_input( 'Please input number1: '))
  38. op = str(raw_input( 'Please input the operation: '))
  39. NumberB = eval(raw_input( 'Please input number2: '))
  40. OPFactory = OperationFatory()
  41. OPType = OPFactory.ChooseOperation(op)
  42. OPType.NumberA = NumberA
  43. OPType.NumberB = NumberB
  44. print 'The result is:',OPType.GetResult()
  45. print '\n#-- input q to exit any key to continue'
  46. try:
  47. ch = str(raw_input())
  48. except:
  49. ch = ''





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值