Python 设计模式之建造者模式 Builder Pattern

 #引入建造者模式

肯德基的菜单上有 薯条, 鸡腿,鸡翅,鸡米花,可乐,橙汁,火腿汉堡,至尊虾汉堡,牛肉汉堡 , 鸡肉卷等这些单品,也有不少套餐。html

好比java

套餐1:鸡翅,至尊虾汉堡,可乐,薯条python

套餐2:鸡腿,火腿汉堡,橙汁,薯条编程

套餐3: 。。。。。segmentfault

全家桶:。。。。。ui

这种有各类各样的单品一步一步生成各类套餐, 这种过程称的上建造者模式htm

 

 使用多个简单的对象一步一步构建成一个复杂的对象,有点像造房子同样一步步从地基作起到万丈高楼。我想这也是为何被称呼为建造者模式的缘由吧!对象

 

 

 

 #建造者定义

 Separate the construction of a complex object from its representation so that the same construction process can create different representations.
将一个复杂对象的构建与它的表示进行分离,使得一样的构建过程能够建立不一样的表示。blog

 

 这个定义里面的 ‘不一样的表示’ 意思是不一样的产品, 或者是不一样的功能。接口

简单理解:建造者模式(Builder Pattern) 具有两层含义:

  • 构建与表示分离构建 表明对象建立,表示 表明对象行为/方法,也就是对象的建立与行为进行分离(对应到 java 代码,其实就是使用 接口 规定行为,而后由具体的实现类进行构建)。
  • 建立不一样的表示:也就是具有一样的行为,可是却因为构建的行为顺序不一样或其余缘由能够建立出不一样的表示。

咱们看完上述 建造者模式 的定义,就知道它与 工厂模式 是很是类似的。构建与表示分离建立不一样的表示 对于 工厂模式 一样具有。建造者模式 惟一区别于 工厂模式 主要是针对 复杂对象的构建

也就是说,若是是建立简单对象,咱们一般都是使用 工厂模式 进行建立;而若是是建立复杂对象,那么此时就能够考虑使用 建造者模式。

 

 

#主要解决

当须要构建的产品具有 复杂建立 过程时,能够抽取出共性构建过程,而后交由具体实现类自定义构建流程,使得一样的构建行为能够生产出不一样的产品,分离了构建与表示,使构建产品灵活性大大增长。

 

 

#使用场景

看到上面的模式定义内容,能够根据内容剥离出这个模式的使用场景

1)须要生成的产品对象有复杂的内部结构,这些产品对象具有共性;

2)隔离复杂对象的建立和使用,并使得相同的构建过程能够建立不一样的产品。

 

 #建造者模式的优势

我在百度文库里看到了这个做者的文章,我喜欢ta的表述,不能复制,我就敲下来放这里了

1)在建造者模式中,客户端没必要知道产品内部组成的细节,将产品自己与产品的建立进行解耦,使得相同的建立过程能够建立不一样的产品对象

2)每个具体建造者都是独立的,与其余的具体建造者无关,,所以能够很方便的替换具体建造者或增长具体建造者,用户使用不一样的具体建造者可获得不一样的产品对象,因为指挥者类针对抽象建造者编程,增长新的具体建造者无需修改原有类库的代码,系统扩展方便,符合开闭原则。在编写代码中,代码复用率是尤其重要的

3)用户能够更为精细的控制产品的建立过程,将复杂的产品的建立步骤分解在不一样的方法中,使得建立过程更加清晰,也更方便使用程序来控制建立过程

 

#建造者模式的缺点

1)建造者模式所建立的产品通常具备较多的共同点,其组成部分类似,若是产品之间的差别性较大,例如不少组成部分不相同,则不适合使用建造者模式,所以使用范围受到必定的限制

2)若是产品的内部变化复杂,可能须要不少具体建造者类类实现这种变化,致使系统变得庞大,增长了系统的理解难度和运行成本

 

 

 

 

#建造者模式 主要包含四种角色:

1)抽象建造者(Builder):主要用于规范产品类的各个组成部分,并提供一个返回完整产品的接口。

2)具体建造者(Concrete Builder):实现 抽象建造者 规定的各个方法,返回一个组件好的具体产品。

3)产品(Product):构建至关复杂的类型,建造者最终建立的产品类型。

4)导演者(Director):指导 建造者(Builder) 以特定行为构建出产品,并将其返回给客户。

总结:理解了 建造者模式 的四种角色,其实就已经掌握了 建造者模式 的真谛:建造者模式 最终返回一个具体的构建复杂的产品;系统中产品可能只有一种类型或多种类型,但对某些产品族来讲,它们具有相同的行为,所以对这些共性行为进行抽象,抽离出 抽象建造者(Builder);而对这些行为的具体构建过程,则交由 具体建造者(Concrete Builder) 负责,不一样的 具体建造者 会构建出不一样表示的产品;而具体要构建出哪一种产品,由 导演者(Director) 决定。导演者 会选择不一样的 具体建造者,指导它构建出产品。

 

#注意,也能够静态内部类实现 建造者模式

事实上,在日常的代码中,咱们一般都会忽略对象的复杂性,使用 工厂模式 建立对象,而不是 建造者模式。正如上文所讲,工厂模式 和 建造者模式 的做用都是用于建立一个产品对象,而 工厂模式 结构更加简洁直接(没有 Builder 和 Director),所以更常使用。

而 建造者模式,咱们更加习惯使用 静态内部类 的方式进行实现,即一个 产品类 内部自动带有一个 具体建造者(Concrete Builder),由它负责该产品的组装建立。再也不须要 抽象建造者(Builder) 和 导演者(Director),这样,使得产品与构建之间的联系更加紧密,结构更加紧凑,同时使得 建造者模式 形式更加简洁。

 

 

#举个例子

 这个订单系统的例子很容易理解,做者写的有点冗余,不过彻底能说明这是一个建造者模式

class Burger():
    """
    主食类,价格名字
    """
    name=""
    price=0.0
    def getPrice(self):
        return self.price
    def setPrice(self,price):
        self.price=price
    def getName(self):
        return self.name
class cheeseBurger(Burger):
    """
    奶酪汉堡
    """
    def __init__(self):
        self.name="cheese burger"
        self.price=10.0
class spicyChickenBurger(Burger):
    """
    香辣鸡汉堡
    """
    def __init__(self):
        self.name="spicy chicken burger"
        self.price=15.0


class Snack():
    """
    小食类,价格以及名字
    """
    name = ""
    price = 0.0
    type = "SNACK"
    def getPrice(self):
        return self.price
    def setPrice(self, price):
        self.price = price
    def getName(self):
        return self.name
class chips(Snack):
    """
    炸薯条
    """
    def __init__(self):
        self.name = "chips"
        self.price = 6.0
class chickenWings(Snack):
    """
    鸡翅
    """
    def __init__(self):
        self.name = "chicken wings"
        self.price = 12.0

class Beverage():
    """
    饮料
    """
    name = ""
    price = 0.0
    type = "BEVERAGE"
    def getPrice(self):
        return self.price
    def setPrice(self, price):
        self.price = price
    def getName(self):
        return self.name
class coke(Beverage):
    """
    可乐
    """
    def __init__(self):
        self.name = "coke"
        self.price = 4.0
class milk(Beverage):
    """
    牛奶
    """
    def __init__(self):
        self.name = "milk"
        self.price = 5.0


class order():
    """
    订单对象,一个订单中包含一份主食,一份小食,一份饮料
    """
    burger=""
    snack=""
    beverage=""
    def __init__(self,orderBuilder):
        self.burger=orderBuilder.bBurger
        self.snack=orderBuilder.bSnack
        self.beverage=orderBuilder.bBeverage
    def show(self):
        print("Burger:%s"%self.burger.getName())
        print("Snack:%s"%self.snack.getName())
        print("Beverage:%s"%self.beverage.getName())

# 建造者
class orderBuilder():
    """
    orderBuilder就是建造者模式中所谓的“建造者”,
    将订单的建造与表示相分离,以达到解耦的目的。
    在上面订单的构建过程当中,若是将order直接经过参数定义好(其构建与表示没有分离),
    同时在多处进行订单生成,此时须要修改订单内容,
    则须要一到处去修改,业务风险也就提升了很多。
    """
    bBurger=""
    bSnack=""
    bBeverage=""
    def addBurger(self,xBurger):
        self.bBurger=xBurger
    def addSnack(self,xSnack):
        self.bSnack=xSnack
    def addBeverage(self,xBeverage):
        self.bBeverage=xBeverage
    def build(self):
        return order(self)

# Director类
class orderDirector():
    """
    在建造者模式中,还能够加一个Director类,用以安排已有模块的构造步骤。
    对于在建造者中有比较严格的顺序要求时,该类会有比较大的用处。
    """
    order_builder=""
    def __init__(self,order_builder):
        self.order_builder=order_builder
    def createOrder(self,burger,snack,beverage):
        self.order_builder.addBurger(burger)
        self.order_builder.addSnack(snack)
        self.order_builder.addBeverage(beverage)
        return self.order_builder.build()

#场景实现
if  __name__=="__main__":
    order_builder=orderBuilder()
    order_builder.addBurger(spicyChickenBurger())
    order_builder.addSnack(chips())
    order_builder.addBeverage(milk())
    order_1=order_builder.build()
    order_1.show()

 

 

 

 

#参考

https://www.jianshu.com/p/47329a94f5dc

https://wenku.baidu.com/view/34a8a76cb9f67c1cfad6195f312b3169a451ea99.html

https://segmentfault.com/a/1190000019414444?utm_source=tag-newest

https://www.jianshu.com/p/9a90ca0fc24f

https://www.cnblogs.com/welan/p/9124081.html

相关文章
相关标签/搜索