使用简单工厂模式来进行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 相关文章推荐
Ubuntu 14.04+Django 1.7.1+Nginx+uwsgi部署教程
Nov 18 Python
解决PyCharm中光标变粗的问题
Aug 05 Python
Python探索之自定义实现线程池
Oct 27 Python
python 列表删除所有指定元素的方法
Apr 19 Python
对pandas中iloc,loc取数据差别及按条件取值的方法详解
Nov 06 Python
python使用Plotly绘图工具绘制柱状图
Apr 01 Python
Python实现的对一个数进行因式分解操作示例
Jun 27 Python
解决Django Static内容不能加载显示的问题
Jul 28 Python
python requests模拟登陆github的实现方法
Dec 26 Python
pytorch VGG11识别cifar10数据集(训练+预测单张输入图片操作)
Jun 24 Python
Python实现图片查找轮廓、多边形拟合、最小外接矩形代码
Jul 14 Python
Python爬虫定时计划任务的几种常见方法(推荐)
Jan 15 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 minixml详解
2008/07/19 PHP
php笔记之:数据类型与常量的使用分析
2013/05/14 PHP
浅析虚拟主机服务器php fsockopen函数被禁用的解决办法
2013/08/07 PHP
既简单又安全的PHP验证码 附调用方法
2016/06/02 PHP
php设计模式之单例模式代码
2016/06/11 PHP
PHP数据对象PDO操作技巧小结
2016/09/27 PHP
php版阿里云OSS图片上传类详解
2016/12/01 PHP
PHP+mysql防止SQL注入的方法小结
2019/04/27 PHP
JS setCapture 区域外事件捕捉
2010/03/18 Javascript
javascript获取和判断浏览器窗口、屏幕、网页的高度、宽度等
2014/05/08 Javascript
node.js中的http.response.writeHead方法使用说明
2014/12/14 Javascript
jQuery实现html元素拖拽
2015/07/21 Javascript
jQuery设置Cookie及删除Cookie实例分析
2016/04/15 Javascript
EasyUI 中combotree 默认不能选择父节点的实现方法
2016/11/07 Javascript
详解node和ES6的模块导出与导入
2020/02/19 Javascript
Python import用法以及与from...import的区别
2015/05/28 Python
Python利用带权重随机数解决抽奖和游戏爆装备问题
2016/06/16 Python
python中学习K-Means和图片压缩
2017/11/20 Python
Python实现简单网页图片抓取完整代码实例
2017/12/15 Python
六行python代码的爱心曲线详解
2019/05/17 Python
Python正则表达式匹配和提取IP地址
2019/06/06 Python
python读文件的步骤
2019/10/08 Python
Python如何实现邮件功能
2020/05/27 Python
python pymysql链接数据库查询结果转为Dataframe实例
2020/06/05 Python
python归并排序算法过程实例讲解
2020/11/04 Python
viagogo法国票务平台:演唱会、体育比赛、戏剧门票
2017/03/27 全球购物
Linux开机引导的步骤是什么
2014/02/26 面试题
Java如何支持I18N?
2016/10/31 面试题
新闻学毕业生自荐信
2013/11/15 职场文书
党的群众路线教育实践活动宣传方案
2014/02/23 职场文书
教师师德师风整改措施
2014/10/24 职场文书
教育教学工作反思
2016/02/24 职场文书
2019思想汇报范文
2019/05/21 职场文书
python实战之90行代码写个猜数字游戏
2021/04/22 Python
pytorch Dropout过拟合的操作
2021/05/27 Python
python 安全地删除列表元素的方法
2022/03/16 Python