[Python设计模式] 第13章 造小人——建造者模式
github地址:https://github.com/cheesezh/python_design_patterns
题目1
用程序模拟一个画小人的过程,要求小人要有头,身子,左手,右手,左脚,右脚。
基础代码
class PersonDrawer():
def draw(self):
print("画头")
print("画身子")
print("画左手")
print("画右手")
print("画左脚")
print("画右脚")
def main():
drawer = PersonDrawer()
drawer.draw()
main()
画头
画身子
画左手
画右手
画左脚
画右脚
题目2
再画一个身子胖一些的小人。
class FatPersonDrawer():
def draw(self):
print("画头")
print("画身子(胖一些)")
print("画左手")
print("画右手")
print("画右脚")
def main():
drawer = FatPersonDrawer()
drawer.draw()
main()
画头
画身子(胖一些)
画左手
画右手
画右脚
点评
画胖一些的小人时候,稍不注意,漏掉了左脚。画小人的步骤很繁琐,稍不注意就会漏掉一步,导致小人缺胳膊少腿。最好的办法就是规定,建造小人的时候,必须要有头,身子,左手,右手,左脚,右脚。这时候就可以使用建造这模式。
建造者模式
建造小人的过程是稳定的,都需要头身手脚,但是具体建造的细节是不同的,高矮胖瘦都有。
为了将一个复杂的对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示,就可以使用建造者模式,又叫“生成器模式”。
实现的方法就是定义抽象的建造者类,通过抽象函数的方法把构建的过程固定下来,这样就每一步也不能少,不会出现缺胳膊少腿的情况了。
from abc import ABCMeta, abstractmethod
class PersonBuilder():
"""
抽象建造者,定义创建对象各个部件的接口
"""
__metaclass__ = ABCMeta
@abstractmethod
def draw_head(self):
pass
@abstractmethod
def draw_body(self):
pass
@abstractmethod
def draw_left_arm(self):
pass
@abstractmethod
def draw_right_arm(self):
pass
@abstractmethod
def draw_left_leg(self):
pass
@abstractmethod
def draw_right_leg(self):
pass
class ThinPersonBuilder(PersonBuilder):
"""
具体建造者,实现创建各个部件的接口
"""
def draw_head(self):
print("画头——瘦小人")
def draw_body(self):
print("画身子——瘦小人")
def draw_left_arm(self):
print("画左手——瘦小人")
def draw_right_arm(self):
print("画右手——瘦小人")
def draw_left_leg(self):
print("画左腿——瘦小人")
def draw_rihgt_leg(self):
print("画右腿——瘦小人")
class FatPersonBuilder(PersonBuilder):
"""
具体建造者,实现创建各个部件的接口
"""
def draw_head(self):
print("画头——胖小人")
def draw_body(self):
print("画身子——胖小人")
def draw_left_arm(self):
print("画左手——胖小人")
def draw_right_arm(self):
print("画右手——胖小人")
def draw_left_leg(self):
print("画左腿——胖小人")
def draw_rihgt_leg(self):
print("画右腿——胖小人")
class PersonDirector():
"""
指挥者,是构建一个使用Builder接口的对象
"""
def __init__(self, person_builder):
self.person_builder = person_builder
def create_person(self):
self.person_builder.draw_head()
self.person_builder.draw_body()
self.person_builder.draw_left_arm()
self.person_builder.draw_right_arm()
self.person_builder.draw_left_leg()
self.person_builder.draw_right_leg()
def main():
thin_person_builder = ThinPersonBuilder()
thin_person_director = PersonDirector(thin_person_builder)
thin_person_director.create_person()
fat_person_builder = FatPersonBuilder()
fat_person_director = PersonDirector(fat_person_builder)
fat_person_director.create_person()
main()
画头——瘦小人
画身子——瘦小人
画左手——瘦小人
画右手——瘦小人
画左腿——瘦小人
画头——胖小人
画身子——胖小人
画左手——胖小人
画右手——胖小人
画左腿——胖小人
点评
建造者模式的好处就是使得建造代码与表示代码分离,由于建造者隐藏了该产品是如何组装的,所以需要改变一个产品的内部表示,只需要再定义一个具体的建造者即可。
建造者模式是在当创建复杂对象的算法应该独立于该对象的组成部分以及它们的装配方式时适用的模式。
[Python设计模式] 第13章 造小人——建造者模式的更多相关文章
- [Python设计模式] 第1章 计算器——简单工厂模式
github地址:https://github.com/cheesezh/python_design_patterns 写在前面的话 """ 读书的时候上过<设计模 ...
- [Python设计模式] 第19章 分公司=部门?——组合模式
github地址:https://github.com/cheesezh/python_design_patterns 组合模式 组合模式,将对象组合成树形结构以表示"部分-整体" ...
- 设计模式(五)Builder Pattern建造者模式
在我们日常生活中,如构建一个飞船,一个手机,一栋建筑,都会有非常复杂的组装,这时候应该用到建造者模式 以建造一个飞船为例 案例:造小页飞船 1.飞船各部分元件 package com.littlepa ...
- 《大话设计模式》ruby版代码:建造者模式
需求: 画一个小人,有头,有身体,两手两脚即可. 初始代码: # -*- encoding: utf-8 -*- #小人一 puts '这是第一个小人' puts '小人一:头' puts '小人一: ...
- 设计模式实战系列之@Builder和建造者模式
前言 备受争议的Lombok,有的人喜欢它让代码更整洁,有的人不喜欢它,巴拉巴拉一堆原因.在我看来Lombok唯一的缺点可能就是需要安装插件了,但是对于业务开发的项目来说,它的优点远远超过缺点. 我们 ...
- .NET设计模式(13):享元模式(Flyweight Pattern)(转)
摘要:面向对象的思想很好地解决了抽象性的问题,一般也不会出现性能上的问题.但是在某些情况下,对象的数量可能会太多,从而导致了运行时的代价.那么我们如何去避免大量细粒度的对象,同时又不影响客户程序使用面 ...
- [Python设计模式] 第21章 计划生育——单例模式
github地址:https://github.com/cheesezh/python_design_patterns 单例模式 单例模式(Singleton Pattern)是一种常用的软件设计模式 ...
- [Python设计模式] 第22章 手机型号&软件版本——桥接模式
github地址:https://github.com/cheesezh/python_design_patterns 紧耦合程序演化 题目1 编程模拟以下情景,有一个N品牌手机,在上边玩一个小游戏. ...
- [Python设计模式] 第16章 上班,干活,下班,加班——状态模式
github地址:https://github.com/cheesezh/python_design_patterns 题目 用代码模拟一天的工作状态,上午状态好,中午想睡觉,下午渐恢复,加班苦煎熬. ...
随机推荐
- oracle数据入库出现空格问题
java做数据入库,不知为什么报如下图错误: debug发现数据是两位,如(FB),但是入库后发现FB后面多了两个空格,检查表发现类型声明是char(4),上网百度,说是char类型会自动补足.参考h ...
- 防止vs编译时自动启动单元测试
Tools → Options → Live Unit Testing Pause 勾选
- 为什么分布式一定要有Redis?
这篇文档是读了一个公众号的文章后修改后复制,以前的学习深度不够,现在还是理解不够,以后再写文档,继续加深. 一:说明 1.说明 考虑到绝大部分写业务的程序员,在实际开发中使用 Redis 的时候,只会 ...
- Python中GIL
GIL(global interpreter lock)全局解释器锁 python中GIL使得同一个时刻只有一个线程在一个cpu上执行,无法将多个线程映射到多个cpu上执行,但GIL并不会一直占有,它 ...
- day 48-css-part1
CSS(Cascading Style Sheet,层叠样式表 css是前端的优化器,如果说我们的html是把前端的大体骨架搭起来的话,那么我们的css就是在这个骨架的基础上进行修饰,使之更有立体感, ...
- P3258 [JLOI2014]松鼠的新家
P3258 [JLOI2014]松鼠的新家倍增lca+树上差分,从叶子节点向根节点求前缀和,dfs求子树和即可,最后,把每次的起点和终点都. #include<iostream> #inc ...
- pwntools简介
安装binutils: git clone https://github.com/Gallopsled/pwntools-binutils sudo apt-get install software- ...
- 表达式语言引擎:Apache Commons JEXL 2.1 发布
http://www.linuxde.net/2011/12/4348.html Commons JEXL 2.1 发布了,该版本和 2.0.1 是二进制兼容的,但源码不兼容,因为新增了两个接口: o ...
- Alpha(5/10)
鐵鍋燉腯鱻 项目:小鱼记账 团队成员 项目燃尽图 冲刺情况描述 站立式会议照片 各成员情况 团队成员 学号 姓名 git地址 博客地址 031602240 许郁杨 (组长) https://githu ...
- MySQL 安装包下载教程
http://www.mysql.com/downloads/