当前位置: 首页 > news >正文

设计模式——建造者模式(生成器模式)总结

当我们需要创建一个非常复杂的对象时,可以使用建造者模式,分步骤建造一个对象,最后将完整的对象返回给客户端。

比如,我们要生成一个房子对象,建造一个房子,需要打地基、盖围墙、盖地板、安装门、安装窗户,有的房子还要盖车库,有的房子还要盖花园,有的房子要盖游泳池,有的。。。总之,房子是个很复杂的对象,涉及上百种不同的配置。

如果我们直接用房子类来创建房子对象,则需要输入几百参数:地基参数、围墙参数、地板参数、门参数、窗户参数,车库参数、花园参数、泳池参数。。等等几百个参数。

参数众多是一个问题,还有一个问题是,可能绝大多数房子用其中一小部分参数就可以了,其他大部分参数则都是压根用不到的,比如有的房子它不要车库,不要花园,不要泳池,那我们如果直接使用房子类来创建房子对象,这么多参数不就是多此一举了吗?

此时,则适宜使用建造者模式。建造者模式中的关键角色是建造者,建造者就像我们现实世界中的工程队一样,它拥有打地基、盖围墙、盖地板等等所有盖房子的众多方法,而我们用户端,则根据我们客户的需要,仅调用我们需要的方法即可。

更进一步,我们可以引入一个建造者主管的角色,建造者主管能够记住我们客户经常调用的建造者技能,比如建造市面上常用的三室一厅的房子,以前我们客户每需要一个三室一厅的房子,需要告诉建造者应该先打地基,再盖地板,再。。。,现在有了建造者主管这个角色,我们客户只需要告诉建造者主管,我需要一个三室一厅的房子就可以了,主管会安排建造者如果使用建造的方法。

建造者模式基本的逻辑就这么多了,这里需要补充两个容易遗漏的点:1,建造者需要有交付房子的方法,这样才能给客户端返回客户需要的房子。2,建造者需要有reset的方法,这样下一个客户调用建造者盖房子时,建造者就会从头开始盖,而不是在上一个房子的基础上继续盖。

实现代码如下:

"""
我们来思考如何创建一个 房屋House对象。 建造一栋简单的房屋, 首先你需要建造四面墙和地板, 安装房门和一套窗户, 然后再建造一个屋顶。
但是如果你想要一栋更宽敞更明亮的房屋, 还要有院子和其他设施 (例如暖气、 排水和供电设备), 那又该怎么办呢?
"""
from abc import ABC,abstractmethod

# 建造者父类
class Builder(ABC):
    def __init__(self):
        self.house = House()
    @abstractmethod
    def build_base(self,number):
        pass
    @abstractmethod
    def build_wall(self,number):
        pass
    @abstractmethod
    def build_roof(self,number):
        pass
    @abstractmethod
    def build_door(self,number):
        pass
    @abstractmethod
    def build_window(self,number):
        pass
    @abstractmethod
    def build_garage(self,number):
        pass
    @abstractmethod
    def build_swimming_pool(self,number):
        pass
    @abstractmethod
    def build_garden(self,number):
        pass
    @abstractmethod
    def deliver_house(self):
        pass

    def reset(self):
        self.house.parts.clear()


class House:
    def __init__(self):
        self.parts = []
    def add(self,facilities):
        self.parts.append(facilities)
    def show(self):
        return f'This house has {','.join(self.parts)}'

# 这是一个建造廉价房子的建造者,他会使用廉价的材料盖房子
class CheapBuilder(Builder):

    def __init__(self):
        super().__init__()

    def build_base(self,number):
        self.house.add(f'{number} cheap bases')


    def build_wall(self,number):
        self.house.add(f'{number} cheap walls')

    def build_roof(self,number):
        self.house.add(f'{number} cheap roofs')

    def build_door(self,number):
        self.house.add(f'{number} cheap doors')

    def build_window(self,number):
        self.house.add(f'{number} cheap windows')

    def build_garage(self,number):
        self.house.add(f'{number} cheap garages')

    def build_swimming_pool(self,number):
        self.house.add(f'{number} cheap swimming pools')

    def build_garden(self,number):
        self.house.add(f'{number} cheap gardens')

    def deliver_house(self):
        return self.house.show()

# 这是一个建造中等质量房子的建造者
class MiddleBuilder(Builder):
    def __init__(self):
        super().__init__()

    def build_base(self, number):
        pass

    def build_wall(self, number):
        pass

    def build_roof(self, number):
        pass

    def build_door(self, number):
        pass

    def build_window(self, number):
        pass

    def build_garage(self, number):
        pass

    def build_swimming_pool(self, number):
        pass

    def build_garden(self, number):
        pass

    def deliver_house(self):
        pass


# 这是一个建造高档房子的建造者
class UpscaleBuilder(Builder):
    def __init__(self):
        super().__init__()

    def build_base(self, number):
        pass

    def build_wall(self, number):
        pass

    def build_roof(self, number):
        pass

    def build_door(self, number):
        pass

    def build_window(self, number):
        pass

    def build_garage(self, number):
        pass

    def build_swimming_pool(self, number):
        pass

    def build_garden(self, number):
        pass

    def deliver_house(self):
        pass

# 这是建造者主管
class Director:
    # 这是主管记住的建造基本房子的方案
    def build_basic_house(self,builder):
        builder.build_base(1)
        builder.build_roof(1)
        builder.build_wall(4)
        builder.build_window(1)
        builder.build_door(1)

    # 这是主管记住的建造最流行的房子的方案
    def build_popular_house(self,builder):
        builder.build_base(1)
        builder.build_roof(1)
        builder.build_wall(4)
        builder.build_window(2)
        builder.build_door(1)
        builder.build_garage(1)

class Client:
    def __init__(self,builder):
        self.director = Director()
        self.builder = builder

    def buy_basic_house(self):
        self.director.build_basic_house(self.builder)

    def get_house(self):
        return self.builder.deliver_house()

if __name__ == "__main__":
    client = Client(CheapBuilder())
    client.buy_basic_house()
    print(client.get_house())

以下是运行结果:
在这里插入图片描述

相关文章:

  • 【从0到1学Elasticsearch】Elasticsearch从入门到精通(上)
  • MySQL 5.7.43 二进制安装指南:从零开始的高效快速实现安装部署
  • 【C++】C与C++、C++内存空间、堆与栈
  • SAX解析XML:Java程序员的“刑侦破案式“数据处理
  • JS的大数运算(注意:原生的只支持整数计算!!!)
  • 四、Appium Inspector
  • 【小沐学GIS】基于C++绘制三维数字地球Earth(QT5、OpenGL、GIS、卫星)第五期
  • 【AI大模型】大模型RAG技术Langchain4j 核心组件深入详解
  • C++项目 —— 基于多设计模式下的同步异步日志系统(2)(工厂模式)
  • CAD 像素点显示图片——CAD二次开发 OpenCV实现
  • c语言 open函数
  • 「OC」小白书读书笔记——Block的相关知识(下)
  • 实现vlan间的通信
  • 解决单设备号双目摄像头调用难题:经验分享与总结
  • 融媒体中心智能语音识别系统设计与实现
  • 第2个小脚本:批量读取所有英文txt文章内容提取高频的单词
  • Matlab学习笔记五十:循环语句和条件语句的用法
  • 【微服务架构】SpringSecurity核心源码剖析+jwt+OAuth(七):SpringSecurity中的权限管理
  • 【HD-RK3576-PI】系统更新与恢复
  • Spring MVC 是如何将 @RequestMapping 注解映射到对应的 Handler 方法?
  • 澎湃·镜相第二届非虚构写作大赛初选入围名单公示
  • 盛和资源海外找稀土矿提速:拟超7亿元收购匹克,加快推动坦桑尼亚项目
  • 法学联合书单|法庭上的妇女
  • 远如《月球背面》,近似你我内心
  • 美国明尼苏达州发生山火,过火面积超80平方公里
  • 俄官员说将适时宣布与乌克兰谈判代表