使用简单工厂模式来进行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 with的用法
Aug 22 Python
Django中对通过测试的用户进行限制访问的方法
Jul 23 Python
python 实时遍历日志文件
Apr 12 Python
Python数据分析之双色球统计单个红和蓝球哪个比例高的方法
Feb 03 Python
python中找出numpy array数组的最值及其索引方法
Apr 17 Python
Python实现的爬取百度文库功能示例
Feb 16 Python
django-rest-framework 自定义swagger过程详解
Jul 18 Python
解析PyCharm Python运行权限问题
Jan 08 Python
Python线程threading模块用法详解
Feb 26 Python
基于python tkinter的点名小程序功能的实例代码
Aug 22 Python
解决Pytorch半精度浮点型网络训练的问题
May 24 Python
健身房被搭讪?用python写了个小米计时器助人为乐
Jun 08 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
PHP中去除换行解决办法小结(PHP_EOL)
2011/11/27 PHP
PHP生成和获取XML格式数据的方法
2016/03/04 PHP
php无法连接mysql数据库的正确解决方法
2016/07/01 PHP
PHP实现简单的模板引擎功能示例
2017/09/02 PHP
PHP中的异常处理机制深入讲解
2020/11/10 PHP
Prototype使用指南之base.js
2007/01/10 Javascript
文本框中,回车键触发事件的js代码[多浏览器兼容]
2010/06/07 Javascript
javascript面向对象之二 命名空间
2011/02/08 Javascript
Javascript计算时间差的函数分享
2011/07/04 Javascript
jquery插件制作 自增长输入框实现代码
2012/08/17 jQuery
JS判断数组中是否有重复值得三种实用方法
2013/08/16 Javascript
JS实现图片横向滚动效果示例代码
2013/09/04 Javascript
JS判断客户端是手机还是PC的2个代码
2014/04/12 Javascript
javascript使用for循环批量注册的事件不能正确获取索引值的解决方法
2014/12/20 Javascript
详细分析使用AngularJS编程中提交表单的方式
2015/06/19 Javascript
jquery实现Ctrl+Enter提交表单的方法
2015/07/21 Javascript
图片旋转、鼠标滚轮缩放、镜像、切换图片js代码
2020/12/13 Javascript
JS中对象与字符串的互相转换详解
2016/05/20 Javascript
javascript显示倒计时控制按钮的简单实现
2016/06/07 Javascript
详解使用angularjs的ng-options时如何设置默认值(初始值)
2017/07/18 Javascript
JS如何生成动态列表
2020/09/22 Javascript
Python学习小技巧之列表项的排序
2017/05/20 Python
Python分析学校四六级过关情况
2017/11/22 Python
python中numpy的矩阵、多维数组的用法
2018/02/05 Python
python自动化报告的输出用例详解
2018/05/30 Python
PyQt5 窗口切换与自定义对话框的实例
2019/06/20 Python
Capitol Lighting的1800lighting.com:住宅和商业照明
2019/04/10 全球购物
苏格兰在线威士忌商店:The Whisky Barrel
2019/05/07 全球购物
世嘉游戏英国官方商店:SEGA Shop UK
2019/09/20 全球购物
美国购物网站:Clickhere2shop
2021/01/28 全球购物
英国户外服装、鞋类和设备的领先零售商:Millets
2020/10/12 全球购物
央视元宵晚会主持串词
2014/03/25 职场文书
中国文明网2015年“向国旗敬礼”活动网上签名寄语
2015/09/24 职场文书
诺贝尔奖获得者名言100句:句句启人心智,值永久收藏
2019/08/09 职场文书
Golang 并发下的问题定位及解决方案
2022/03/16 Golang
MySQL限制查询和数据排序介绍
2022/03/25 MySQL