《Head First 设计模式》笔记17-建造者模式

  1. 定义
  2. 模式结构
  3. 代码示例
  4. 优缺点
  5. 建造者模式与抽象工厂模式的比较

定义

建造者模式(Builder Pattern):将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。也叫生成器模式。

建造者模式的关键特性是它将一个建造过程分解成很多步骤,也可以说,每个产品的建造会遵循同样的流程,不过流程内的每一个步骤都不尽相同。

模式结构

建造者模式包含如下角色:

  • Builder:抽象建造者。它声明为创建一个 Product 对象的各个部件指定的抽象接口。
  • ConcreteBuilder:具体建造者。实现抽象接口,构建和装配各个部件。
  • Director:指挥者。构建一个使用 Builder 接口的对象。它主要是用于创建一个复杂的对象,它主要有两个作用,一是:隔离了客户与对象的生产过程,二是:负责控制产品对象的生产过程。
  • Product:产品角色。一个具体的产品对象。

代码示例

KFC 里面一般都有好几种可供客户选择的套餐,它可以根据客户所点的套餐,然后在后面做这些套餐,返回给客户的事一个完整的、美好的套餐。下面我们将会模拟这个过程,我们约定套餐主要包含汉堡、薯条、可乐、鸡腿等等组成部分,使用不同的组成部分就可以构建出不同的套餐。

首先是套餐类:Meal.java

public class Meal {
    private String food;
    private String drink;

    public String getFood() {
        return food;
    }

    public void setFood(String food) {
        this.food = food;
    }

    public String getDrink() {
        return drink;
    }

    public void setDrink(String drink) {
        this.drink = drink;
    }
}

然后是套餐构造器:MealBuilder.java

public abstract class MealBuilder {
    Meal meal = new Meal();

    public abstract void buildFood();

    public abstract void buildDrink();

    public Meal getMeal(){
        return meal;
    }
}

然后是套餐 A、套餐 B。这个两个套餐都是实现抽象套餐类。

public class MealA extends MealBuilder{

    public void buildDrink() {
        meal.setDrink("一杯可乐");
    }
    public void buildFood() {
        meal.setFood("一盒薯条");
    }

}
public class MealB extends MealBuilder{

    public void buildDrink() {
        meal.setDrink("一杯柠檬果汁");
    }
    public void buildFood() {
        meal.setFood("三个鸡翅");
    }
}

最后是 KFC 的服务员,它相当于一个指挥者,它决定了套餐是的实现过程,然后给你一个完美的套餐。

public class KFCWaiter {
    private MealBuilder mealBuilder;

    public void setMealBuilder(MealBuilder mealBuilder) {
        this.mealBuilder = mealBuilder;
    }

    public Meal construct(){
        //准备食物
        mealBuilder.buildFood();
        //准备饮料
        mealBuilder.buildDrink();

        //准备完毕,返回一个完整的套餐给客户
        return mealBuilder.getMeal();
    }
}

测试类

public class Client {
    public static void main(String[] args) {
        //服务员
        KFCWaiter waiter = new KFCWaiter();
        //套餐A
        MealA a = new MealA();
        //服务员准备套餐A
        waiter.setMealBuilder(a);
        //获得套餐
        Meal mealA = waiter.construct();

        System.out.print("套餐A的组成部分:");
        System.out.println(mealA.getFood()+"---"+mealA.getDrink());
    }
}

运行结果:

套餐 A 的组成部分: 一盒薯条 --- 一杯可乐

优缺点

优点

  1. 将复杂产品的创建步骤分解在不同的方法中,使得创建过程更加清晰,使得我们能够更加精确的控制复杂对象的产生过程。
  2. 将产品的创建过程与产品本身分离开来,可以使用相同的创建过程来得到不同的产品。也就说细节依赖抽象。
  3. 每一个具体建造者都相对独立,而与其他的具体建造者无关,因此可以很方便地替换具体建造者或增加新的具体建造者,用户使用不同的具体建造者即可得到不同的产品对象。

缺点

  1. 建造者模式所创建的产品一般具有较多的共同点,其组成部分相似,如果产品之间的差异性很大,则不适合使用建造者模式,因此其使用范围受到一定的限制。
  2. 如果产品的内部变化复杂,可能会导致需要定义很多具体建造者类来实现这种变化,导致系统变得很庞大。

建造者模式与抽象工厂模式的比较

  • 与抽象工厂模式相比,建造者模式返回一个组装好的完整产品 ,而抽象工厂模式返回一系列相关的产品,这些产品位于不同的产品等级结构,构成了一个产品族
  • 在抽象工厂模式中,客户端实例化工厂类,然后调用工厂方法获取所需产品对象,而在建造者模式中,客户端可以不直接调用建造者的相关方法,而是通过指挥者类来指导如何生成对象,包括对象的组装过程和建造步骤,它侧重于一步步构造一个复杂对象,返回一个完整的对象。
  • 如果将抽象工厂模式看成汽车配件生产工厂,生产一个产品族的产品,那么建造者模式就是一个汽车组装工厂,通过对部件的组装可以返回一辆完整的汽车。

转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 bin07280@qq.com

文章标题:《Head First 设计模式》笔记17-建造者模式

文章字数:1.3k

本文作者:Bin

发布时间:2018-08-01, 23:17:57

最后更新:2019-08-06, 00:07:35

原始链接:http://coolview.github.io/2018/08/01/Head-First-%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/%E3%80%8AHead-First-%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E3%80%8B%E7%AC%94%E8%AE%B017-%E5%BB%BA%E9%80%A0%E8%80%85%E6%A8%A1%E5%BC%8F/

版权声明: "署名-非商用-相同方式共享 4.0" 转载请保留原文链接及作者。

目录