zoukankan      html  css  js  c++  java
  • 设计模式之建造者模式

      建造者模式属于创建型设计模式,它提供了一种创建对象的最佳方式。

      定义:将一个复杂对象的构造与它的表示分离,使同样的构建过程可以创建不同的表示。

      问题描述:创建一个复杂的对象,它是由多个其它对象“组装”而来的,并且随着“组装元件”的不同而不同。

      解决方案:将复杂对象的创建和使用分离开来,并使得相同的创建过程可以创建出不同的产品。

      结构图

      说明:

      (1)Builder:抽象建造者,为创建一个产品对象的各个部件定义的抽象接口。buildPartX()方法用于复杂产品的各个部分;getProduct()方法用于返回创建的结果。

      (2)ConcreteBuilder:具体建造者,实现了Builder接口,创建一种复杂的具体产品。

      (3)Product:具体产品类,包含多个组成部分,由具体建造者创建。

      (4)Director:指挥类,负责安排复杂对象的组装次序,与建造者存在关联关系。使用者只需要和指挥类交互就可以完成复杂产品的创建,不需要知道复杂产品的创建细节。

      举个栗子:讲一个肯德基套餐的故事。。。

      我们都去过KFC,每个套餐的配料不同,自然价格也不一。比如(价格虚构,请勿当真):

      A套餐:香辣鸡腿堡、薯条手卷和雪碧,价格30元;

      B套餐:板烧鸡腿堡、香酥炸薯条和九珍果汁,价格36元;

      C套餐:超级鸡腿堡、螺旋薯条14和可口可乐,价格42元。

      接下来,我们就用建造者模式来实现创建这三种套餐并记录各套餐详情和价格的功能,具体实现方式如下:

      (1)创建套餐的组成类,均继承父类BaseFood,香辣鸡腿堡SpicyChickenBurger、板烧鸡腿堡TepChickenBurger、超级鸡腿堡SuperChickenBurger、薯条书卷HandFrenchFries、香酥炸薯条SpicyFrenchFries、螺旋薯条ScrewFrenchFries、雪碧SpriteBeverage、九珍果汁FruitJuiceBeverage和可口可乐CocaColaBeverage。代码如下:

               

                

        其它组成类雷同,此处省略。

      (2)创建抽象建造者IMealBuilder,因为三个套餐都有同一种属性,那就是大致分为三个组成部分,汉堡、薯条和饮料,所以我们就在接口中定义这三个方法,再加上一个返回创建结果产品类Meal对象的方法。其中类Meal依赖BaseFood,符合里氏替换原则,包含添加套餐成分、展示套餐详情和计算套餐总价三个方法。代码如下:

                

                

      (3)分别创建三个具体建造者,A套餐具体建造者AMealBuilder,B套餐具体建造者BMealBuilder,C套餐具体建造者CMealBuilder,实现IMealBuilder接口中的方法。代码如下:

               

               

               

      (4)创建一个指挥类MealDirector,依赖接口IMealBuilder,符合依赖倒置原则,它来负责创建不同的套餐。代码如下:

               

      (5)在类BuilderFragment中通过指挥类MealDirector实例来获取套餐类对象Meal,实现创建不同套餐对象并记录其详情和价格的功能。代码如下:

               

      (6)运行后的结果,如下所示:

                

      综上所述,建造者模式是来解决创建一个复杂对象的问题,使用者只需指定对象的类型,而不需要知道具体建造细节。在实现的过程中,我们会想到抽象工厂模式,似乎实现方式大致相同,其实不然,建造者模式和抽象工厂模式还是有区别的,抽象工厂模式返回的是一系列相关的产品,而建造者模式只返回一种产品,其中的组成部分是可以灵活多变的,只是复杂对象的整体结构不能变,比如套餐的组成类别,就只能是汉堡、薯条和饮料这三种,所以建造者模式存在一定的局限性。

      优点

      1. 使用者不需要知道产品的组成细节,将产品本身和产品的创建过程解耦,使得相同的创建过程可以创建不同的产品对象;

      2. 每一个具体建造者对应着不同的产品对象,它们之间是相对独立的,可以很方便地替换具体建造者或增加新的具体建造者;

      3. 指挥类针对抽象建造者编程,增加新的具体建造者时无需修改原有的代码,只需要新增一个具体建造者类并实现抽象建造者接口中的方法即可,系统扩展方便,并且符合开闭原则;

      4. 可以更加精细地控制产品的创建过程。将复杂产品的创建步骤分解在不同的方法中,使得创建过程更佳清晰,而且创建次序可以随意调整。

      缺点

      1. 产品的整体结构固定,唯一可以改变的是产品的组成部分。如果产品的结构类型差别很大,那么就不适用于建造者模式了;

      2. 如果产品的种类较多且产品的创建比较复杂,那么就需要使用更多的具体建造者来实现,这样就会导致系统变得越来越庞大,甚至不易维护。

      适用场景

      1. 需要生成的产品对象内部结构比较复杂,但是都包含多个成员属性,成员种类存在一定的相似之处。

      2. 需要生成的产品对象的属性相互依赖,需要指定其生存顺序;

      3. 复杂对象的创建过程独立于创建该对象的类;

      4. 隔离复杂对象的创建和使用,并使得相同的创建过程可以创建出不同的产品。

  • 相关阅读:
    Java基础_0205: 程序逻辑结构
    java基础_0204:运算符
    Centos 7 安装MySQL
    Maven 入门
    winx64 MySQL 5.7绿色版安装步骤
    hadoop环境搭建
    配置虚拟机 Linux 静态IP
    JDK开发环境搭建及环境变量配置
    设计模式之命令模式详解(故事版)
    设计模式之 外观模式详解(Service第三者插足,让action与dao分手)
  • 原文地址:https://www.cnblogs.com/chenxkang/p/6725160.html
Copyright © 2011-2022 走看看