使用简单工厂模式来进行Python的设计模式编程


Posted in Python onMarch 01, 2016

计模式的目的是让代码易维护、易扩展,不能为了模式而模式,因此一个简单的工具脚本是不需要用到任何模式的。

简单工厂模式又叫静态工厂方法模式,工厂模式家族中最简单的一种模式。这个模式的基本工作方式: 通过一个工厂来决定创建哪种具体的产品实例。

下面是一个简单的工厂实例:

def create_animal(name):
 if name == 'dog':
  return Dog()
 elif name == 'cat':
  return Cat()

animal = create_animal('dog')
animal.eat('some food')

create_animal就是一个工厂,各种动物就是产品,该工厂根据name来决定产出什么动物产品。产品应该具有一个基本特性,同一个工厂出产的所有产品都是一个系列,都具有相同的功能,比如动物都吃食物。

简单工厂模式的好处是可以将产品对象的细节封装在其实现类的内部,改变一个产品对象具体实现不会影响其他产品。可扩展性强,当需要新增产品类型时,只需要添加对应的实现类,然后修改工厂,增加一个判断分支即可。修改工厂函数带来的风险比较低。

另外一个比较典型的适合简单工厂模式的例子是计算器,计算器需要支持各种计算操作,比如加、减、乘、除、平方、立方、平方根、阶乘等等。那么这里的工厂就是要创建各种操作算法对象,每种操作算法对象都支持一个求值方法。

def create_operator(op):
 if op == '+':
  return AddOperation()
 elif op == '-':
  return SubOperation()
 elif op == '*':
  return MulOperation()
 elif op == '/':
  return DivOperation()

op = create_operator('+')
op.Calc(1, 2)

前面提到,每个工厂生产的产品都是一个系列的,因此产品类通常会从同一个抽象基类派生,但不是必须的。

简单工厂模式的组成要素:
工厂函数:负责具体产品对象的创建工作,是该模式的核心。当场景比较复杂时,可能需要用一个工厂类来负责产品的创建。
以及产品的抽象接口或抽象类、抽象所有产品的公共接口、具体产品类、抽象接口的具体实现类。

缺点:
由于工厂类集中了所有实例的创建逻辑,违反了高内聚责任分配原则,将全部创建逻辑集中到了一个工厂类中
它所能创建的类只能是事先考虑到的,如果需要添加新的类,则就需要改变工厂类了
当系统中的具体产品类不断增多时候,可能会出现要求工厂类根据不同条件创建不同实例的需求.这种对条件的判断和对具体产品类型的判断交错在一起,很难避免模块功能的蔓延,对系统的维护和扩展非常不利;

使用场景:
工厂类负责创建的对象比较少;
客户只知道传入工厂类的参数,对于如何创建对象(逻辑)不关心;
由于简单工厂很容易违反高内聚责任分配原则,因此一般只在很简单的情况下应用。


eg:采用简单工厂模式实现计算器

#encoding=utf-8 
# 
#by panda 
#简单工厂模式 
 
class OperateBase(): 
 result = 0; 
 def GetResult(self): 
  return self.result; 
 
class OperationAdd(OperateBase): 
 def __init__(self, NumA, NumB): 
  self.result = NumA + NumB; 
 def GetResult(self): 
  return self.result;   
  
class OperationSub(OperateBase): 
 def __init__(self, NumA, NumB): 
  self.result = NumA - NumB; 
 def GetResult(self): 
  return self.result; 
  
class OperationMult(OperateBase): 
 def __init__(self, NumA, NumB): 
  self.result = NumA * NumB; 
 def GetResult(self): 
  return self.result; 
 
class OperationDiv(OperateBase): 
 def __init__(self, NumA, NumB): 
  self.result = NumA / NumB; 
 def GetResult(self): 
  return self.result; 
 
class OperationFactory(): 
 @staticmethod 
 def createOperate(operate, NumA, NumB): 
  optList = { 
  '+':OperationAdd, 
  '-':OperationSub, 
  '*':OperationMult, 
  '/':OperationDiv,   
  } 
  oper = OperateBase() 
  if(optList.has_key(operate)): 
   oper = optList[operate](NumA, NumB);   
  return oper 
 
 
def clientUI(): 
 opt = raw_input("please input a operation(+-*/): "); 
 NumA = raw_input("please input the first number: "); 
 NumB = raw_input("please input the second number: ");  
 oper = OperationFactory.createOperate(opt, float(NumA), float(NumB)) 
 print "Restlt: ", oper.GetResult() 
 return 
 
if __name__ == '__main__': 
 clientUI();

UML类图如下:

使用简单工厂模式来进行Python的设计模式编程

Python 相关文章推荐
Python中的列表知识点汇总
Apr 14 Python
Python切片知识解析
Mar 06 Python
python实现决策树C4.5算法详解(在ID3基础上改进)
May 31 Python
Python自定义简单图轴简单实例
Jan 08 Python
Django学习教程之静态文件的调用详解
May 08 Python
Python OpenCV处理图像之图像像素点操作
Jul 10 Python
浅谈Python 多进程默认不能共享全局变量的问题
Jan 11 Python
Python with用法:自动关闭文件进程
Jul 10 Python
如何基于python操作excel并获取内容
Dec 24 Python
浅析PyCharm 的初始设置(知道)
Oct 12 Python
详解Python流程控制语句
Oct 28 Python
Pytorch实现WGAN用于动漫头像生成
Mar 04 Python
Python文件处理
Feb 29 #Python
python 默认参数问题的陷阱
Feb 29 #Python
简要讲解Python编程中线程的创建与锁的使用
Feb 28 #Python
Python中time模块和datetime模块的用法示例
Feb 28 #Python
python 写的一个爬虫程序源码
Feb 28 #Python
Python基础语法(Python基础知识点)
Feb 28 #Python
python中map()与zip()操作方法
Feb 27 #Python
You might like
ajax+php实现无刷新验证手机号的实例
2017/12/22 PHP
PHP上传图片到数据库并显示的实例代码
2019/12/20 PHP
屏蔽鼠标右键、Ctrl+n、shift+F10、F5刷新、退格键 的javascript代码
2007/04/01 Javascript
用js生产批量批处理执行命令
2008/07/28 Javascript
ASP.NET jQuery 实例7 通过jQuery来获取DropDownList的Text/Value属性值
2012/02/03 Javascript
JS实现的左侧竖向滑动菜单效果代码
2015/10/19 Javascript
BootStrap的Datepicker控件使用心得分享
2016/05/25 Javascript
微信小程序去哪里找 小程序到底如何使用(附小程序名单)
2017/01/09 Javascript
Vue.directive自定义指令的使用详解
2017/03/10 Javascript
jQuery validata插件实现方法
2017/06/25 jQuery
vue.js 底部导航栏 一级路由显示 子路由不显示的解决方法
2018/03/09 Javascript
30分钟快速入门掌握ES6/ES2015的核心内容(下)
2018/04/18 Javascript
javascript显示动态时间的方法汇总
2018/07/06 Javascript
React父子组件间的传值的方法
2018/11/13 Javascript
Vue.js 中的 v-model 指令及绑定表单元素的方法
2018/12/03 Javascript
zepto.js 实时监听输入框的方法
2018/12/04 Javascript
vue 中url 链接左边的小图标更改问题
2019/12/30 Javascript
vue自定义组件(通过Vue.use()来使用)即install的用法说明
2020/08/11 Javascript
在Python中使用全局日志时需要注意的问题
2015/05/06 Python
Python自定义简单图轴简单实例
2018/01/08 Python
python自动发送邮件脚本
2018/06/20 Python
python对list中的每个元素进行某种操作的方法
2018/06/29 Python
Python程序包的构建和发布过程示例详解
2019/06/09 Python
Python自动抢红包教程详解
2019/06/11 Python
计算pytorch标准化(Normalize)所需要数据集的均值和方差实例
2020/01/15 Python
pip安装tensorflow的坑的解决
2020/04/19 Python
tensorflow图像裁剪进行数据增强操作
2020/06/30 Python
解决Python安装cryptography报错问题
2020/09/03 Python
HTML5实现锚点时请使用id取代name
2013/09/06 HTML / CSS
Toppik顶丰增发纤维官网:解决头发稀疏
2017/12/30 全球购物
2019年Java面试必问之经典试题
2012/09/12 面试题
EntityManager都有哪些方法
2013/11/01 面试题
中年人生感言
2014/02/04 职场文书
奉献家乡演讲稿
2014/09/13 职场文书
教师师德工作总结2015
2015/07/22 职场文书
Feign调用全局异常处理解决方案
2021/06/24 Java/Android