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章 造小人——建造者模式的更多相关文章

  1. [Python设计模式] 第1章 计算器——简单工厂模式

    github地址:https://github.com/cheesezh/python_design_patterns 写在前面的话 """ 读书的时候上过<设计模 ...

  2. [Python设计模式] 第19章 分公司=部门?——组合模式

    github地址:https://github.com/cheesezh/python_design_patterns 组合模式 组合模式,将对象组合成树形结构以表示"部分-整体" ...

  3. 设计模式(五)Builder Pattern建造者模式

    在我们日常生活中,如构建一个飞船,一个手机,一栋建筑,都会有非常复杂的组装,这时候应该用到建造者模式 以建造一个飞船为例 案例:造小页飞船 1.飞船各部分元件 package com.littlepa ...

  4. 《大话设计模式》ruby版代码:建造者模式

    需求: 画一个小人,有头,有身体,两手两脚即可. 初始代码: # -*- encoding: utf-8 -*- #小人一 puts '这是第一个小人' puts '小人一:头' puts '小人一: ...

  5. 设计模式实战系列之@Builder和建造者模式

    前言 备受争议的Lombok,有的人喜欢它让代码更整洁,有的人不喜欢它,巴拉巴拉一堆原因.在我看来Lombok唯一的缺点可能就是需要安装插件了,但是对于业务开发的项目来说,它的优点远远超过缺点. 我们 ...

  6. .NET设计模式(13):享元模式(Flyweight Pattern)(转)

    摘要:面向对象的思想很好地解决了抽象性的问题,一般也不会出现性能上的问题.但是在某些情况下,对象的数量可能会太多,从而导致了运行时的代价.那么我们如何去避免大量细粒度的对象,同时又不影响客户程序使用面 ...

  7. [Python设计模式] 第21章 计划生育——单例模式

    github地址:https://github.com/cheesezh/python_design_patterns 单例模式 单例模式(Singleton Pattern)是一种常用的软件设计模式 ...

  8. [Python设计模式] 第22章 手机型号&软件版本——桥接模式

    github地址:https://github.com/cheesezh/python_design_patterns 紧耦合程序演化 题目1 编程模拟以下情景,有一个N品牌手机,在上边玩一个小游戏. ...

  9. [Python设计模式] 第16章 上班,干活,下班,加班——状态模式

    github地址:https://github.com/cheesezh/python_design_patterns 题目 用代码模拟一天的工作状态,上午状态好,中午想睡觉,下午渐恢复,加班苦煎熬. ...

随机推荐

  1. oralce不像Java,java中字符串+数字,能够得到结果字符串

    oracle得到的两个字段进行相加,要求都是number类型的,如果两个是字符串会自动转成number类型(前提是能够转) select a+b from (select '1' a,'2' b fr ...

  2. RBM:深度学习之Restricted Boltzmann Machine的BRBM学习+LR分类—Jason niu

    from __future__ import print_function print(__doc__) import numpy as np import matplotlib.pyplot as ...

  3. Django之模板基础

    Django之模板 目录 变量 过滤器 标签的使用 变量 变量的引用格式 使用双括号,两边空格不能省略. 语法格式: {{var_name}} Template和Context对象 context 字 ...

  4. RFC2616-HTTP1.1-Methods(方法规定部分—译文)

    part of Hypertext Transfer Protocol -- HTTP/1.1RFC 2616 Fielding, et al. 9 方法定义 下面列出了有关HTTP/1.1协议的一些 ...

  5. Mybatis之延迟加载机制

    1.  延迟加载的含义: 用到的时候才会去进行相关操作 2.  延迟加载的例子: 2.1 spring的BeanFactory,在getBean()的时候才创建Bean 2.2 物理分页查询,只有点击 ...

  6. Spring:获取容器中的Bean

    某些情况下我们要获取 IOC 容器中指定注解.类型.名字的 Bean 要获取 IOC 容器中指定条件的 Bean 可以通过 ApplicationContext 相应的方法 @Autowired pr ...

  7. 机器学习模型从windows下 spring上传到预发布会导致模型不可加载

    1.通过上传到redis,程序通过redis拉取模型,解决问题. 2.问题原因初步思考为windows下模型文件上传到 linux导致,待继续跟进查找.

  8. Java笔记(一)编程基础与二进制

    编程基础与二进制 一.编程基础 函数调用的基本原理: 函数调用中的问题: 1)参数如何传递? 2)函数如何知道返回什么地方? 3)函数结果如何传递给调用方? 解决思路是使用内存来函数调用过程中需要的数 ...

  9. python系统编程(十)

    多线程-非共享数据 对于全局变量,在多线程中要格外小心,否则容易造成数据错乱的情况发生 1. 非全局变量是否要加锁呢? #coding=utf-8 import threading import ti ...

  10. ZKW线段树入门

    Part 1 来说说它的构造 线段树的堆式储存 我们来转成二进制看看 小学生问题:找规律 规律是很显然的 一个节点的父节点是这个数左移1,这个位运算就是低位舍弃,所有数字左移一位 一个节点的子节点是这 ...