• python实现建造者模式


    python实现建造者模式

    前言

    无论是在现实世界中还是在软件系统中,都存在一些复杂的对象,它们拥有多个组成部分,如汽车,它包括车轮、方向盘、发送机等各种部件。而对于大多数用户而言,无须知道这些部件的装配细节,也几乎不会使用单独某个部件,而是使用一辆完整的汽车,可以通过建造者模式对其进行设计与描述,建造者模式可以将部件和其组装过程分开,一步一步创建一个复杂的对象。用户只需要指定复杂对象的类型就可以得到该对象,而无须知道其内部的具体构造细节.

    介绍

    建造者模式(Builder Pattern 又名生成器模式,是一种对象构建模式。它可以将复杂对象的建造过程抽象出来(抽象类别),使这个抽象过程的不同实现方法可以构造出不同表现(属性)的对象。

    建造者模式 是一步一步创建一个复杂的对象,它允许用户只通过指定复杂对象的类型和内容就可以构建它们,用户不需要知道内部的具体构建细节。

    主要解决:主要解决在软件系统中,有时候面临着"一个复杂对象"的创建工作,其通常由各个部分的子对象用一定的算法构成;由于需求的变化,这个复杂对象的各个部分经常面临着剧烈的变化,但是将它们组合在一起的算法却相对稳定。

    何时使用:一些基本部件不会变,而其组合经常变化的时候。

    如何解决:将变与不变分离开。

    关键代码:建造者:创建和提供实例,指挥者:管理建造出来的实例的依赖关系。

    应用实例: 去肯德基,汉堡、可乐、薯条、炸鸡翅等是不变的,而其组合是经常变化的,生成出所谓的"套餐"。

    优点: 1、建造者独立,易扩展。 2、便于控制细节风险。

    缺点: 1、产品必须有共同点,范围有限制。 2、如内部变化复杂,会有很多的建造类。

    使用场景: 1、需要生成的对象具有复杂的内部结构。 2、需要生成的对象内部属性本身相互依赖。

    注意事项:与工厂模式的区别是:建造者模式更加关注与零件装配的顺序。

     

    实例:KFC套餐

    建造者模式可以用于描述KFC如何创建套餐:套餐是一个复杂对象,它一般包含主食(如汉堡、鸡肉卷等)和饮料(如果汁、可乐等)等组成部分,不同的套餐有不同的组成部分,而KFC的服务员可以根据顾客的要求,一步一步装配这些组成部分,构造一份完整的套餐,然后返回给顾客。

    #具体产品对象
    class Menu:
        Menu_A=[]
        Menu_B=[]
        def set_MenuA(self,item):
            self.Menu_A.append(item)
        def set_MenuB(self,item):
            self.Menu_B.append(item)
        def get_MenuA(self):
            return self.Menu_A
        def get_MenuB(self):
            return self.Menu_B
    
    # Builder(抽象建造者)
    # 创建一个Product对象的各个部件指定的抽象接口。
    class Product:
        product = Menu()
        def build_hanbao(self):
            pass
        def build_jiroujuan(self):
            pass
        def build_kele(self):
            pass
        def build_shutiao(self):
            pass
    
    # ConcreteBuilder(具体建造者)
    # 实现抽象接口,构建和装配各个部件。
    #套餐A
    class product_A(Product):
        type="A"
        def build_hanbao(self):
            self.hanbao="汉堡"
            self.product.set_MenuA(self.hanbao)
        def build_kele(self):
            self.kele="可乐"
            self.product.set_MenuA(self.kele)
        def getType(self):
            return type
    
    # 套餐B
    class product_B(Product):
        type = "B"
        def build_shutiao(self):
            self.shutiao="薯条"
            self.product.set_MenuB(self.shutiao)
        def build_jiroujuan(self):
            self.jiroujuan="鸡肉卷"
            self.product.set_MenuB(self.jiroujuan)
        def build_kele(self):
            self.kele="可乐"
            self.product.set_MenuB(self.kele)
        def getType(self):
            return type
    
    #Director(指挥者)
    class Make:
        def __init__(self):
            self.builder = None
        def build_product(self, builder):
            self.builder = builder
            print(builder.type)
            if builder.type == "A":
                [step() for step in (builder.build_hanbao,
                builder.build_kele)]
            if builder.type == "B":
                [step() for step in (builder.build_shutiao,
                                     builder.build_jiroujuan,
                                     builder.build_kele)]
    
    #不同类型选择
    def validate_style(builders):
        global valid_input
        try:
            print('套餐A:汉堡、可乐'+'
    '
                  '套装B:薯条、鸡肉卷、可乐')
            product_style = input('请输入您的选择:' )
            builder = builders[product_style]()
            valid_input = True
        except KeyError as err:
            print('Sorry, 没有这个套餐,请重新选择。')
            return (False, None)
        return (True, builder,product_style)
    
    #主函数
    def main():
        builders = dict(A=product_A, B=product_B)
        valid_input = False
        while not valid_input:
            valid_input, builder,product_style = validate_style(builders)
        Waiter = Make()
        Waiter.build_product(builder)
        if product_style == "A":print(builder.product.get_MenuA())
        else:print(builder.product.get_MenuB())
    
    if __name__ =="__main__":
        main()

    输出

    套餐A:汉堡、可乐
    套装B:薯条、鸡肉卷、可乐
    请输入您的选择:A
    A
    ['汉堡', '可乐']
  • 相关阅读:
    【Android命令行】apktool参数详解
    【Android】ANR+OOM+FC
    如何创建低成本沙箱环境?推荐你使用API仿真!
    关于代码覆盖率,你不可不知的两大陷阱!
    如何借助自动创建单元测试来提高单元测试的投资回报率(ROI)?
    [实用指南]如何使您的旧代码库(遗留代码)符合MISRA C 2012编码规范?
    超实用的10个技巧!让您无论使用哪种静态分析工具都能轻松更新现有的静态分析实现
    主数据管理(MDM)的6大层级简述,你不可不知的数据治理参考!
    【收藏】关于元数据(Metadata)和元数据管理,这是我的见过最全的解读!
    机器学习 | 基于机器学习的供应链管理之销售库存优化分析(实操分享)
  • 原文地址:https://www.cnblogs.com/-wenli/p/10965106.html
Copyright © 2020-2023  润新知