深入解析Python设计模式编程中建造者模式的使用


Posted in Python onMarch 02, 2016

建造者模式:将一个复杂对象的构建与他的表示分离,使得同样的构建过程可以创建不同的表示。

基本思想
某类产品的构建由很多复杂组件组成;
这些组件中的某些细节不同,构建出的产品表象会略有不同;
通过一个指挥者按照产品的创建步骤来一步步执行产品的创建;
当需要创建不同的产品时,只需要派生一个具体的建造者,重写相应的组件构建方法即可。

代码结构

class Builder(object):
  """基类"""
  def Part1(self):
    # 不同类型的产品,该步骤的细节可能不同
    raise NotImplementedError()

  def Part2(self):
    # 不同类型的产品,该步骤的细节可能不同
    raise NotImplementedError()

class Builder1(Builder):
  """派生类,生产builder1类型的产品"""
  def Part1(self):
    print 'builder1 Part1'

  def Part2(self):
    print 'builder1 Part2'

class Builder2(Builder):
  """派生类,生产builder2类型的产品"""
  def Part1(self):
    print 'builder2 Part1'

  def Part2(self):
    print 'builder2 Part2'

class Director(object):
  """指挥者,负责组织产品的构建过程"""
  def Build(self, builder):
    builder.Part1()
    builder.Part2()

def client():
  director = Director()
  director.Build(Builder1())
  director.Build(Builder2())

这里有一个疑问,指挥者这个角色有什么用呢。感觉除了增加client的调用负担外,似乎没什么用处。为什么不把产品构建过程放在Builder基类中呢,像下面这样:

class Builder(object):
  """基类"""
  def Part1(self):
    raise NotImplementedError()

  def Part2(self):
    raise NotImplementedError()

  def Build(self):
    self.Part1()
    self.Part2()

class Builder1(Builder):
  def Part1(self):
    print 'builder1 Part1'

  def Part2(self):
    print 'builder1 Part2'

class Builder2(Builder):
  def Part1(self):
    print 'builder2 Part1'

  def Part2(self):
    print 'builder2 Part2'

def client():
  Builder1().Build()
  Builder2().Build()

没错,上面就是典型的模板方法模式的实现套路,回顾一下模板方法模式的定义: > 模板方法模式:定义一个工作流或算法的基本骨架,而将一些特定步骤的实现延迟到子类中。

模板方法模式更多的关注于算法流程,而建造者模式更多的关注于复杂对象的创建,模板模式应用场景比建造者模式更多一些,写起来也更自然一些。

类图

深入解析Python设计模式编程中建造者模式的使用

实例

#encoding=utf-8 
# 
#by panda 
#建造者模式 
 
 
def printInfo(info): 
  print unicode(info, 'utf-8').encode('gbk') 
 
#建造者基类 
class PersonBuilder(): 
  def BuildHead(self): 
    pass 
   
  def BuildBody(self): 
    pass 
   
  def BuildArm(self): 
    pass 
 
  def BuildLeg(self): 
    pass 
   
#胖子 
class PersonFatBuilder(PersonBuilder): 
  type = '胖子' 
  def BuildHead(self): 
    printInfo("构建%s的头" % self.type) 
   
  def BuildBody(self): 
    printInfo("构建%s的身体" % self.type) 
   
  def BuildArm(self): 
    printInfo("构建%s的手" % self.type) 
 
  def BuildLeg(self): 
    printInfo("构建%s的脚" % self.type) 
   
 
#瘦子 
class PersonThinBuilder(PersonBuilder): 
  type = '瘦子' 
  def BuildHead(self): 
    printInfo("构建%s的头" % self.type) 
   
  def BuildBody(self): 
    printInfo("构建%s的身体" % self.type) 
   
  def BuildArm(self): 
    printInfo("构建%s的手" % self.type) 
 
  def BuildLeg(self): 
    printInfo("构建%s的脚" % self.type) 
 
#指挥者 
class PersonDirector(): 
  pb = None; 
  def __init__(self, pb): 
    self.pb = pb 
   
  def CreatePereson(self): 
    self.pb.BuildHead() 
    self.pb.BuildBody() 
    self.pb.BuildArm() 
    self.pb.BuildLeg() 
 
def clientUI(): 
  pb = PersonThinBuilder() 
  pd = PersonDirector(pb) 
  pd.CreatePereson() 
   
  pb = PersonFatBuilder() 
  pd = PersonDirector(pb) 
  pd.CreatePereson() 
  return 
 
 
if __name__ == '__main__': 
  clientUI();
Python 相关文章推荐
深入理解python try异常处理机制
Jun 01 Python
Python实现八大排序算法
Aug 13 Python
判断python字典中key是否存在的两种方法
Aug 10 Python
python对于requests的封装方法详解
Jan 03 Python
远程部署工具Fabric详解(支持Python3)
Jul 04 Python
Python解析多帧dicom数据详解
Jan 13 Python
浅谈python之自动化运维(Paramiko)
Jan 31 Python
浅谈pandas.cut与pandas.qcut的使用方法及区别
Mar 03 Python
python实现扑克牌交互式界面发牌程序
Apr 22 Python
tensorflow实现从.ckpt文件中读取任意变量
May 26 Python
Python3利用openpyxl读写Excel文件的方法实例
Feb 03 Python
Python就将所有的英文单词首字母变成大写
Feb 12 Python
举例讲解Python设计模式编程中对抽象工厂模式的运用
Mar 02 #Python
实例讲解Python设计模式编程之工厂方法模式的使用
Mar 02 #Python
详解设计模式中的工厂方法模式在Python程序中的运用
Mar 02 #Python
探究python中open函数的使用
Mar 01 #Python
Saltstack快速入门简单汇总
Mar 01 #Python
通过Python使用saltstack生成服务器资产清单
Mar 01 #Python
Python解析json文件相关知识学习
Mar 01 #Python
You might like
Joomla下利用configuration.php存储简单数据
2010/05/19 PHP
php命名空间设计思想、用法与缺点分析
2019/07/17 PHP
用js实现判断当前网址的来路如果不是指定的来路就跳转到指定页面
2011/05/02 Javascript
Extjs显示从数据库取出时间转换JSON后的出现问题
2012/11/20 Javascript
如何用js控制frame的隐藏或显示的解决办法
2013/03/20 Javascript
在Node.js中实现文件复制的方法和实例
2014/06/05 Javascript
js实现上传图片预览的方法
2015/02/09 Javascript
laypage分页控件使用实例详解
2016/05/19 Javascript
javascript宿主对象之window.navigator详解
2016/09/07 Javascript
关于Vue.nextTick()的正确使用方法浅析
2017/08/25 Javascript
js使用xml数据载体实现城市省份二级联动效果
2017/11/08 Javascript
Vue父组件调用子组件事件方法
2018/02/23 Javascript
JS实现自定义弹窗功能
2018/08/08 Javascript
vue 右键菜单插件 简单、可扩展、样式自定义的右键菜单
2018/11/29 Javascript
Python编程实现输入某年某月某日计算出这一天是该年第几天的方法
2017/04/18 Python
Python 获得命令行参数的方法(推荐)
2018/01/24 Python
在pycharm中设置显示行数的方法
2019/01/16 Python
详解python做UI界面的方法
2019/02/27 Python
通过pycharm使用git的步骤(图文详解)
2019/06/13 Python
python opencv 二值化 计算白色像素点的实例
2019/07/03 Python
使用python将多个excel文件合并到同一个文件的方法
2019/07/09 Python
详解Python用三种方式统计词频的方法
2019/07/29 Python
Python 格式化输出_String Formatting_控制小数点位数的实例详解
2020/02/04 Python
Python批量安装卸载1000个apk的方法
2020/04/10 Python
Python脚本如何在bilibili中查找弹幕发送者
2020/06/04 Python
python使用selenium爬虫知乎的方法示例
2020/10/28 Python
中专自荐信
2013/10/13 职场文书
优秀少先队工作者事迹材料
2014/05/13 职场文书
机械设计制造及其自动化专业求职信
2014/06/17 职场文书
爱国主义教育演讲稿
2014/08/26 职场文书
班主任高考寄语
2015/02/26 职场文书
复兴之路观后感
2015/06/02 职场文书
2016最新离婚协议书范本及程序
2016/03/18 职场文书
一文读懂go中semaphore(信号量)源码
2021/04/03 Golang
Django开发RESTful API实现增删改查(入门级)
2021/05/10 Python
CSS控制继承中的height能变为可继承吗
2022/06/10 HTML / CSS