深入解析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 相关文章推荐
浅谈django中的认证与登录
Oct 31 Python
Python2.X/Python3.X中urllib库区别讲解
Dec 19 Python
python中文编码与json中文输出问题详解
Aug 24 Python
Python实现随机创建电话号码的方法示例
Dec 07 Python
Python3.5内置模块之os模块、sys模块、shutil模块用法实例分析
Apr 27 Python
numpy下的flatten()函数用法详解
May 27 Python
Python的Lambda函数用法详解
Sep 03 Python
关于Keras模型可视化教程及关键问题的解决
Jan 24 Python
python pandas移动窗口函数rolling的用法
Feb 29 Python
分布式全文检索引擎ElasticSearch原理及使用实例
Nov 14 Python
如何通过一篇文章了解Python中的生成器
Apr 02 Python
详解Golang如何实现支持随机删除元素的堆
Sep 23 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
动态新闻发布的实现及其技巧
2006/10/09 PHP
php如何解决无法上传大于8M的文件问题
2014/03/10 PHP
Joomla调用系统自带编辑器的实现方法
2016/05/05 PHP
Yii2实现同时搜索多个字段的方法
2016/08/10 PHP
PHP实现mysqli批量执行多条语句的方法示例
2017/07/22 PHP
Yii redis集合的基本使用教程
2020/06/14 PHP
Javascript中的Split使用方法与技巧
2007/03/09 Javascript
JQuery团队打造的javascript单元测试工具QUnit介绍
2010/02/26 Javascript
JQuery 选择和过滤方法代码总结
2010/11/19 Javascript
页面调用单个swf文件,嵌套出多个方法。
2011/11/21 Javascript
createElement与createDocumentFragment的点点区别小结
2011/12/19 Javascript
js导航栏单击事件背景变换示例代码
2014/01/13 Javascript
js控制再次点击按钮之间的间隔时间可防止重复提交
2014/08/01 Javascript
推荐9款炫酷的基于jquery的页面特效
2014/12/07 Javascript
JS实现动态给图片添加边框的方法
2015/04/01 Javascript
JS实现的鼠标跟随代码(卡通手型点击效果)
2015/10/26 Javascript
九种原生js动画效果
2015/11/11 Javascript
解析Vue 2.5的Diff算法
2017/11/28 Javascript
webpack将js打包后的map文件详解
2018/02/22 Javascript
vue实现在表格里,取每行的id的方法
2018/03/09 Javascript
node.js 模块和其下载资源的镜像设置的方法
2018/09/06 Javascript
python的Template使用指南
2014/09/11 Python
简单的python协同过滤程序实例代码
2018/01/31 Python
Python常用字符串替换函数strip、replace及sub用法示例
2018/05/21 Python
使用PyQt的QLabel组件实现选定目标框功能的方法示例
2020/05/19 Python
Keras load_model 导入错误的解决方式
2020/06/09 Python
CSS3基础(RGBa、text-shadow、box-shadow、border-radius)
2012/11/13 HTML / CSS
css3的transition效果和transfor效果示例介绍
2013/10/30 HTML / CSS
Steve Madden官网:美国鞋类品牌
2017/01/29 全球购物
澳大利亚工具仓库:Tools Warehouse
2018/10/15 全球购物
座谈会主持词
2014/03/20 职场文书
经典禁毒标语
2014/06/16 职场文书
工程款申请报告
2015/05/15 职场文书
关于战胜挫折的名言警句大全!
2019/07/05 职场文书
Golang 实现获取当前函数名称和文件行号等操作
2021/05/08 Golang
悬疑名作《朋友游戏》动画无字ED宣传片 新角色公开
2022/04/13 日漫