码猿技术专栏

微信公众号:码猿技术专栏

设计模式之建造模式

定义

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

  • 简单说,建造者的功能就是先构造复杂对象的每一个部件,指挥者的功能就是将这些部件以一定的步骤组装起来,形成一个具有一定功能的产品或者对象。当然这个步骤是透明的对于客户端。

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

建造者模式

实例

  • 下面是一个组装汽车的例子,其中汽车由发动机和轮胎组成,那么我们只需要组装轮胎,发动机即可组装完成一个汽车。

  • 汽车包括轮胎,引擎,我们通常在组装汽车的时候一般都是一步一步的组装,比如先装引擎,后装轮胎。使用建造者模式就是将建造汽车的这个过程抽离成几个不同的过程,比如建造引擎和建造轮胎就是两个过程。

  • 轮胎的JavaBean

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    /*
    * 轮胎
    */
    class Tyre {
    private String name;

    public Tyre(String name) {
    this.name = name;
    }

    public String getName() {
    return name;
    }

    public void setName(String name) {
    this.name = name;
    }

    }
  • 引擎的JavaBean

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    /*
    * 引擎
    */
    class Engine {

    private String name;

    public Engine(String name) {
    this.name = name;
    }

    public String getName() {
    return name;
    }

    public void setName(String name) {
    this.name = name;
    }

    }

  • 汽车的JavaBean(汽车包含轮胎和引擎,因此使用聚合的关系)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    /*
    * 汽车的类
    */
    public class Car {

    private Tyre tyre; // 轮胎
    private Engine engine; // 引擎

    public Tyre getTyre() {
    return tyre;
    }

    public void setTyre(Tyre tyre) {
    this.tyre = tyre;
    }

    public Engine getEngine() {
    return engine;
    }

    public void setEngine(Engine engine) {
    this.engine = engine;
    }
    }
  • 抽象建造者(实际上是一个接口,其中定义了建造轮胎和引擎的方法)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    public interface Builder {
    /**
    * 构造引擎的方法
    */
    Engine buliderEngine();

    /**
    * 构造轮胎的方法
    */
    Tyre builderTyre();
    }
  • 具体的建造者(实现了抽象建造者,实现建造轮胎和引擎的详细过程)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    /*
    * 具体的建造者,主要是构造汽车的部件
    */
    public class BuilderCar implements Builder {
    @Override
    public Engine buliderEngine() {
    System.out.println("构造汽车发动机");
    return new Engine("傻逼牌发动机");
    }

    @Override
    public Tyre builderTyre() {
    System.out.println("构造汽车轮胎");
    return new Tyre("傻逼牌轮胎");
    }
    }
  • 抽象指挥者(定义了一个构造汽车的方法),指挥者的作用就是按照一定步骤将构造者建造的部件组装起来

    1
    2
    3
    4
    5
    6
    7
    /*
    * 指挥者的接口,用来按照顺序组装汽车
    */
    public interface Director {
    Car CreateCar();
    }

  • 具体的指挥者(实现了指挥者接口)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    /*
    * 指挥者的实现类
    */
    public class DirectorCar implements Director {

    private Builder builder; // 建造者的对象

    /**
    * 构造方法,主要用来初始化建造者对象
    *
    * @param builder Builder的对象
    */
    public DirectorCar(Builder builder) {
    this.builder = builder;
    }

    @Override
    public Car CreateCar() {
    Car car = new Car(); // 创建汽车对象
    Engine engine = builder.buliderEngine(); // 构建发动机
    Tyre tyre = builder.builderTyre(); // 构造轮胎
    car.setEngine(engine); // 设置属性
    car.setTyre(tyre); // 设置属性
    return car; // 返回构造好的汽车
    }
    }
  • 测试类
    1
    2
    3
    4
    5
    6
    7
    8
    public class Client {
    public static void main(String[] args) {
    Director director = new DirectorCar(new BuilderCar()); // 创建指挥者的对象
    Car car = director.CreateCar(); // 获取组装完成的
    System.out.println(car.getEngine().getName()); // 输出引擎的名字
    System.out.println(car.getTyre().getName()); // 输出轮胎的名字
    }
    }

适用场景

  • 基本部件不变,但是其中的组合经常变化的情况

    • 比如你去肯德基点餐,汉堡,可乐,鸡翅这些食物是不变的,但是套餐的组合是经常变化的,建造者模式的指挥者就是将这些部件按照一定步骤将其组合起来的。
    • java中StringBuilder
  • 需要生成的对象具有复杂的内部结构

    • 复杂的内部结构,我们可以使用建造者模式将其分离,先将其中的各个小的部件组装成功,然后由指挥者按照一定的步骤将其组装成一个复杂的对象
  • 需要生成的对象内部属性本身相互依赖。

笔者有话说

  • 最近建了一个微信交流群,提供给大家一个交流的平台,扫描下方笔者的微信二维码,备注【交流】,我会把大家拉进群

欢迎关注我的其它发布渠道