深入解析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基础教程之udp端口扫描
Feb 10 Python
使用django-suit为django 1.7 admin后台添加模板
Nov 18 Python
python解决网站的反爬虫策略总结
Oct 26 Python
django初始化数据库的实例
May 27 Python
详解python中list的使用
Mar 15 Python
python将四元数变换为旋转矩阵的实例
Dec 04 Python
python绘制规则网络图形实例
Dec 09 Python
如何基于python测量代码运行时间
Dec 25 Python
Python 字典中的所有方法及用法
Jun 10 Python
python某漫画app逆向
Mar 31 Python
PyQt5爬取12306车票信息程序的实现
May 14 Python
Python实现科学占卜 让视频自动打码
Apr 09 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
PHP 多维数组排序实现代码
2009/08/05 PHP
twig模板获取全局变量的方法
2016/02/05 PHP
php使用PDO事务配合表格读取大量数据插入操作实现方法
2017/02/16 PHP
解决FLASH需要点击激活的代码
2006/12/20 Javascript
fromCharCode和charCodeAt 方法
2006/12/27 Javascript
IE下window.onresize 多次调用与死循环bug处理方法介绍
2013/11/12 Javascript
JavaScript中具名函数的多种调用方式总结
2014/11/08 Javascript
Node.js中JavaScript操作MySQL的常用方法整理
2016/03/01 Javascript
一道面试题引发的对javascript类型转换的思考
2017/03/06 Javascript
vue2.0开发入门笔记之.vue文件的生成和使用
2017/09/19 Javascript
详解React之父子组件传递和其它一些要点
2018/06/25 Javascript
jquery 插件重新绑定的处理方法分析
2019/11/23 jQuery
Python中的集合类型知识讲解
2015/08/19 Python
Windows下为Python安装Matplotlib模块
2015/11/06 Python
Python实现的多线程同步与互斥锁功能示例
2017/11/30 Python
Python基于列表list实现的CRUD操作功能示例
2018/01/05 Python
完美解决Pycharm无法导入包的问题 Unresolved reference
2018/05/18 Python
python读取xlsx的方法
2018/12/25 Python
Python告诉你木马程序的键盘记录原理
2019/02/02 Python
Python类中的魔法方法之 __slots__原理解析
2019/08/26 Python
Python MOCK SERVER moco模拟接口测试过程解析
2020/04/13 Python
Python改变对象的字符串显示的方法
2020/08/01 Python
Html5 canvas实现粒子时钟的示例代码
2018/09/06 HTML / CSS
丝芙兰加拿大官方网站:SEPHORA加拿大
2018/11/20 全球购物
Skyscanner香港:机票比价, 平机票和廉价航空机票预订
2020/02/07 全球购物
局域网标准
2016/09/10 面试题
企业宣传方案
2014/03/04 职场文书
技校毕业生自荐信
2014/06/03 职场文书
销售内勤岗位职责
2015/02/10 职场文书
隐形的翅膀观后感
2015/06/10 职场文书
演讲比赛主持词
2015/06/29 职场文书
行政处罚告知书
2015/07/01 职场文书
Oracle设置DB、监听和EM开机启动的方法
2021/04/25 Oracle
Keras在mnist上的CNN实践,并且自定义loss函数曲线图操作
2021/05/25 Python
css常用字体属性与背景属性介绍
2022/02/28 HTML / CSS
《吸血鬼幸存者》新内容发布 追加多个全新模式
2022/04/07 其他游戏