使用简单工厂模式来进行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之模块的加载
Oct 24 Python
浅谈python中截取字符函数strip,lstrip,rstrip
Jul 17 Python
Python操作使用MySQL数据库的实例代码
May 25 Python
Tensorflow实现卷积神经网络的详细代码
May 24 Python
Python装饰器知识点补充
May 28 Python
详解Django+Uwsgi+Nginx的生产环境部署
Jun 25 Python
使用python Fabric动态修改远程机器hosts的方法
Oct 26 Python
python命令行工具Click快速掌握
Jul 04 Python
python图片指定区域替换img.paste函数的使用
Apr 09 Python
解决python cv2.imread 读取中文路径的图片返回为None的问题
Jun 02 Python
Python OpenCV读取中文路径图像的方法
Jul 02 Python
python Cartopy的基础使用详解
Nov 01 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开发留言板的CRUD(增,删,改,查)操作
2012/04/19 PHP
基于empty函数的判断详解
2013/06/17 PHP
php简单实现sql防注入的方法
2016/04/22 PHP
PHP获取指定日期是星期几的实现方法
2016/11/30 PHP
php7性能提升的原因详解
2019/10/13 PHP
用htc组件制作windows选项卡
2007/01/13 Javascript
半角全角相互转换的js函数
2009/10/16 Javascript
Extjs学习笔记之二 初识Extjs之Form
2010/01/07 Javascript
jQuery使用removeClass方法删除元素指定Class的方法
2015/03/26 Javascript
jQuery关键词说明插件cluetip使用指南
2015/04/21 Javascript
谈谈encodeURI和encodeURIComponent以及escape的区别与应用
2015/11/24 Javascript
Google 地图API资料整理及详细介绍
2016/08/06 Javascript
JS动态的把左边列表添加到右边的实现代码(可上下移动)
2016/11/17 Javascript
jQuery实现导航栏头部菜单项点击后变换颜色的方法
2017/07/19 jQuery
JS中的BOM应用
2018/02/02 Javascript
Angular使用cli生成自定义文件、组件的方法
2018/09/04 Javascript
JavaScript使用闭包模仿块级作用域操作示例
2019/01/21 Javascript
vue项目创建并引入饿了么elementUI组件的步骤
2019/04/11 Javascript
微信小程序获取用户绑定手机号方法示例
2019/07/21 Javascript
vue 基于abstract 路由模式 实现页面内嵌的示例代码
2020/12/14 Vue.js
Python的自动化部署模块Fabric的安装及使用指南
2016/01/19 Python
Python基于ThreadingTCPServer创建多线程代理的方法示例
2018/01/11 Python
python 2.7 检测一个网页是否能正常访问的方法
2018/12/26 Python
django框架使用orm实现批量更新数据的方法
2019/06/21 Python
Python3加密解密库Crypto的RSA加解密和签名/验签实现方法实例
2020/02/11 Python
Python DataFrame使用drop_duplicates()函数去重(保留重复值,取重复值)
2020/07/20 Python
HTML5中在title标题标签里设置小图标的方法
2020/06/23 HTML / CSS
临床医学专业个人的自我评价
2013/09/27 职场文书
汉语言文学专业自荐信
2014/06/11 职场文书
合作协议书格式
2014/08/19 职场文书
影视广告专业求职信
2014/09/02 职场文书
css3带你实现3D转换效果
2022/02/24 HTML / CSS
《Estab Life》4月6日播出 正式PV、主视觉图公开
2022/03/20 日漫
golang使用map实现去除重复数组
2022/04/14 Golang
BCL经典机 SONY ICF-5900W电路分析
2022/04/24 无线电
Java完整实现记事本代码
2022/06/16 Java/Android