python版简单工厂模式


Posted in Python onOctober 16, 2017

什么是简单工厂模式

工厂模式有一种非常形象的描述,建立对象的类就如一个工厂,而需要被建立的对象就是一个个产品;在工厂中加工产品,使用产品的人,不用在乎产品是如何生产出来的。从软件开发的角度来说,这样就有效的降低了模块之间的耦合。
简单工厂的作用是实例化对象,而不需要客户了解这个对象属于哪个具体的子类。简单工厂实例化的类具有相同的接口或者基类,在子类比较固定并不需要扩展时,可以使用简单工厂。如数据库生产工厂就是简单工厂的一个应用
采用简单工厂的优点是可以使用户根据参数获得对应的类实例,避免了直接实例化类,降低了耦合性;缺点是可实例化的类型在编译期间已经被确定,如果增加新类 型,则需要修改工厂,不符合OCP(开闭原则)的原则。简单工厂需要知道所有要生成的类型,当子类过多或者子类层次过多时不适合使用。

简单工厂模式实现

下面考虑《大话设计模式》中的一个例子:
题目:用任意一种面向对象语言实现一个计算器控制台程序。要求输入两个数和运算符号,得到结果。

题目分析:

程序应该做到:(1)可维护;(2)可复用;(3)可扩展;(4)灵活性好。
可维护:就是说代码一处更改,不能产生连锁反应,不能影响其他地方。
可复用:尽量减少重复性代码。
可扩展:如果要扩展新的功能、新的业务,则只需要增加新的类就好了,不对已有的类和逻辑产生影响。插拔式的应用。
面向对象要点:
面向对象三大特性:封装、继承、多态。
通过封装、继承、多态把程序耦合降低。
业务逻辑和界面逻辑分开。

类的结构图:

python版简单工厂模式

代码实现:

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

2. 例如现在这个运算器只有加减乘除四种运算。首先建一个Operation类,这个类是各种具体运算类(加减乘除)的父类,主要是接受用户输入的数值。该类如下:

class Operation(): 
  def __init__(self,NumberA=0,NumberB=0): 
    self.NumberA = NumberA 
    self.NumberB = NumberB 
 
  def GetResult(self): 
    pass

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

class AddOp(Operation): 
  def GetResult(self): 
    return self.NumberB + self.NumberA 
 
class MinusOp(Operation): 
  def GetResult(self): 
    return self.NumberA - self.NumberB 
 
class MultiOp(Operation): 
  def GetResult(self): 
    return self.NumberA * self.NumberB 
 
class DivideOp(Operation): 
  def GetResult(self): 
    try: 
      return 1.0*self.NumberA / self.NumberB 
    except ZeroDivisionError: 
      raise

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

class OperationFatory(): 
  def ChooseOperation(self,op): 
    if op == '+': 
      return AddOp() 
    if op == '-': 
      return MinusOp() 
    if op == '*': 
      return MultiOp() 
    if op == '/': 
      return DivideOp()

5. 这样,用户只要输入运算符,工厂类就可以创建合适的实例,通过多态性,即返回给父类的方式实现运算结果。客户端代码如下:

if __name__ == '__main__': 
  ch = '' 
  while not ch=='q':  
    NumberA = eval(raw_input('Please input number1: ')) 
    op = str(raw_input('Please input the operation: ')) 
    NumberB = eval(raw_input('Please input number2: ')) 
    OPFactory = OperationFatory() 
    OPType = OPFactory.ChooseOperation(op) 
    OPType.NumberA = NumberA 
    OPType.NumberB = NumberB 
    print 'The result is:',OPType.GetResult() 
    print '\n#-- input q to exit any key to continue' 
    try: 
      ch = str(raw_input()) 
    except: 
      ch = ''

完整版代码如下:

# -*-coding:UTF-8-*-  
from abc import ABCMeta,abstractmethod 
 
class Operation(): 
  def __init__(self,NumberA=0,NumberB=0): 
    self.NumberA = NumberA 
    self.NumberB = NumberB 
 
  def GetResult(self): 
    pass 
 
class AddOp(Operation): 
  def GetResult(self): 
    return self.NumberB + self.NumberA 
 
class MinusOp(Operation): 
  def GetResult(self): 
    return self.NumberA - self.NumberB 
 
class MultiOp(Operation): 
  def GetResult(self): 
    return self.NumberA * self.NumberB 
 
class DivideOp(Operation): 
  def GetResult(self): 
    try: 
      return 1.0*self.NumberA / self.NumberB 
    except ZeroDivisionError: 
      raise 
 
class OperationFatory(): 
  def ChooseOperation(self,op): 
    if op == '+': 
      return AddOp() 
    if op == '-': 
      return MinusOp() 
    if op == '*': 
      return MultiOp() 
    if op == '/': 
      return DivideOp() 
 
if __name__ == '__main__': 
  ch = '' 
  while not ch=='q':  
    NumberA = eval(raw_input('Please input number1: ')) 
    op = str(raw_input('Please input the operation: ')) 
    NumberB = eval(raw_input('Please input number2: ')) 
    OPFactory = OperationFatory() 
    OPType = OPFactory.ChooseOperation(op) 
    OPType.NumberA = NumberA 
    OPType.NumberB = NumberB 
    print 'The result is:',OPType.GetResult() 
    print '\n#-- input q to exit any key to continue' 
    try: 
      ch = str(raw_input()) 
    except: 
      ch = ''

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
Python的标准模块包json详解
Mar 13 Python
python编程线性回归代码示例
Dec 07 Python
Python实现简易版的Web服务器(推荐)
Jan 29 Python
Python中__slots__属性介绍与基本使用方法
Sep 05 Python
使用EduBlock轻松学习Python编程
Oct 08 Python
解决pyshp UnicodeDecodeError的问题
Dec 06 Python
完美解决pycharm 不显示代码提示问题
Jun 02 Python
细说NumPy数组的四种乘法的使用
Dec 18 Python
用python发送微信消息
Dec 21 Python
matplotlib自定义鼠标光标坐标格式的实现
Jan 08 Python
Python实现王者荣耀自动刷金币的完整步骤
Jan 22 Python
python爬虫--selenium模块
Mar 31 Python
Python实现扩展内置类型的方法分析
Oct 16 #Python
Python使用文件锁实现进程间同步功能【基于fcntl模块】
Oct 16 #Python
python利用paramiko连接远程服务器执行命令的方法
Oct 16 #Python
基于使用paramiko执行远程linux主机命令(详解)
Oct 16 #Python
python中文件变化监控示例(watchdog)
Oct 16 #Python
python中import reload __import__的区别详解
Oct 16 #Python
使用Python操作excel文件的实例代码
Oct 15 #Python
You might like
叶罗丽:为什么大家对颜冰这对CP非常关心,却对金茉两人十分冷漠
2020/03/17 国漫
thinkPHP分组后模板无法加载问题解决方法
2016/07/12 PHP
py文件转exe时包含paramiko模块出错解决方法
2016/08/12 PHP
PHP实现使用DOM将XML数据存入数组的方法示例
2017/09/27 PHP
Laravel5.7框架安装与使用学习笔记图文详解
2019/04/02 PHP
Ruffy javascript 学习笔记
2009/11/30 Javascript
js实现的跟随鼠标移动的时钟效果(中英文日期显示)
2011/01/17 Javascript
JQuery获取浏览器窗口内容部分高度的代码
2012/02/24 Javascript
javascript的渐进增强与平稳退化浅谈
2013/11/12 Javascript
JavaScript读二进制文件并用ajax传输二进制流的方法
2016/07/18 Javascript
JavaScript 函数模式详解及示例
2016/09/07 Javascript
微信小程序 实战实例开发流程详细介绍
2017/01/05 Javascript
jQuery插件FusionCharts实现的3D帕累托图效果示例【附demo源码】
2017/03/25 jQuery
node实现定时发送邮件的示例代码
2017/08/26 Javascript
浅谈Angular HttpClient简单入门
2018/05/04 Javascript
利用js将ajax获取到的后台数据动态加载至网页中的方法
2018/08/08 Javascript
VUE实现密码验证与提示功能
2019/10/18 Javascript
js常用方法、检查是否有特殊字符串、倒序截取字符串操作完整示例
2020/01/26 Javascript
Vue+Openlayers自定义轨迹动画
2020/09/24 Javascript
el-table表头根据内容自适应完美解决表头错位和固定列错位
2021/01/07 Javascript
python实现删除文件与目录的方法
2014/11/10 Python
ubuntu安装mysql pycharm sublime
2018/02/20 Python
Python读写及备份oracle数据库操作示例
2018/05/17 Python
keras的load_model实现加载含有参数的自定义模型
2020/06/22 Python
如何通过Python实现RabbitMQ延迟队列
2020/11/28 Python
美国知名的女性服饰品牌:LOFT(洛芙特)
2016/08/05 全球购物
GAZMAN官网:澳大利亚领先的男装品牌
2019/12/19 全球购物
学生党员思想汇报范文
2014/01/09 职场文书
三年级语文教学反思
2014/02/01 职场文书
产品质量承诺书范文
2014/03/27 职场文书
车辆工程专业求职信
2014/04/28 职场文书
党的群众路线查摆剖析材料
2014/10/10 职场文书
2015年试用期工作总结范文
2015/05/28 职场文书
2016教师给学生的毕业寄语
2015/12/04 职场文书
Java比较两个对象中全部属性值是否相等的方法
2021/08/07 Java/Android
星际争霸 Light vs Action 一场把教主看到鬼畜的比赛
2022/04/01 星际争霸