使用简单工厂模式来进行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聊天室实现方法
Jun 28 Python
Python学习小技巧之利用字典的默认行为
May 20 Python
Python正则表达式完全指南
May 25 Python
Python tkinter模块弹出窗口及传值回到主窗口操作详解
Jul 28 Python
Python+PIL实现支付宝AR红包
Feb 09 Python
浅谈pandas用groupby后对层级索引levels的处理方法
Nov 06 Python
Python3开发环境搭建详细教程
Jun 18 Python
Python判断远程服务器上Excel文件是否被人打开的方法
Jul 13 Python
Python Selenium XPath根据文本内容查找元素的方法
Dec 07 Python
opencv python 对指针仪表读数识别的两种方式
Jan 14 Python
python爬虫scrapy框架的梨视频案例解析
Feb 20 Python
python制作图形界面的2048游戏, 基于tkinter
Apr 06 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
声音就能俘获人心,蕾姆,是哪个漂亮小姐姐配音呢?
2020/03/03 日漫
php 变量定义方法
2009/06/14 PHP
PHP学习笔记 用户注册模块用户类以及验证码类
2011/09/20 PHP
PHP获取数组最后一个值的2种方法
2015/01/21 PHP
详解Grunt插件之LiveReload实现页面自动刷新(两种方案)
2015/07/31 PHP
WordPress中调试缩略图的相关PHP函数使用解析
2016/01/07 PHP
PHP使用内置函数生成图片的方法详解
2016/05/09 PHP
ThinkPHP5+UEditor图片上传到阿里云对象存储OSS功能示例
2019/08/05 PHP
ExtJS Ext.MessageBox.alert()弹出对话框详解
2010/04/02 Javascript
js动态修改input输入框的type属性(实现方法解析)
2013/11/13 Javascript
jQuery 隐藏和显示 input 默认值示例
2014/06/03 Javascript
node.js中的buffer.length方法使用说明
2014/12/14 Javascript
JavaScript焦点事件、鼠标事件和滚轮事件使用详解
2016/01/15 Javascript
Bootstrap实现弹性搜索框
2016/07/11 Javascript
JavaScript 函数模式详解及示例
2016/09/07 Javascript
Cookies 和 Session的详解及区别
2017/04/21 Javascript
Sublime Text新建.vue模板并高亮(图文教程)
2017/10/26 Javascript
JavaScript禁用右键单击优缺点分析
2019/01/20 Javascript
Vue 3.0 前瞻Vue Function API新特性体验
2019/08/12 Javascript
微信小程序页面滚动到指定位置代码实例
2019/09/07 Javascript
vue vantUI tab切换时 list组件不触发load事件的问题及解决方法
2020/02/14 Javascript
JS实现网页端猜数字小游戏
2020/03/06 Javascript
jQuery实现鼠标拖拽登录框移动效果
2020/09/13 jQuery
Python 基础教程之包和类的用法
2017/02/23 Python
python中异常捕获方法详解
2017/03/03 Python
urllib和BeautifulSoup爬取维基百科的词条简单实例
2018/01/17 Python
将Python文件打包成.EXE可执行文件的方法
2019/08/11 Python
Python利用PyPDF2库获取PDF文件总页码实例
2020/04/03 Python
PyCharm MySQL可视化Database配置过程图解
2020/06/09 Python
纯CSS3实现图片无间断轮播效果
2016/08/25 HTML / CSS
文秘专业应届生求职信范文
2013/11/14 职场文书
工程专业求职自荐书范文
2014/02/08 职场文书
简易离婚协议书范本
2014/10/24 职场文书
2016年九九重阳节活动总结
2016/04/01 职场文书
用Python爬取各大高校并可视化帮弟弟选大学,弟弟直呼牛X
2021/06/11 Python
手写Spirit防抖函数underscore和节流函数lodash
2022/03/22 Javascript