「补课」进行时:设计模式(4)——建造者模式

1. 前文汇总

「补课」进行时:设计模式系列

2. 建造者模式定义

建造者模式(Builder Pattern)也叫做生成器模式,其定义如下:

Separate the construction of a complex object from its representation sothat the same construction process can create different representations.(将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。)

通用类图:

  • Product: 产品类,通常是实现了模板方法模式,也就是有模板方法和基本方法。
  • Builder: 抽象建造者,规范产品的组建,一般是由子类实现。
  • ConcreteBuilder: 具体建造者,实现抽象类定义的所有方法,并且返回一个组建好的对象。
  • Director: 导演类,负责安排已有模块的顺序,然后告诉 Builder 开始建造。

通用代码示例:

Product 产品类:

public class Product {
    public void doSomething() {
        // 业务处理
    }
}

Builder 抽象建造者:

public abstract class Builder {
    // 设置产品不同的部分,用来获得不同的产品
    abstract void setPart();
    // 建造产品
    abstract Product buildProduct();
}

ConcreteBuilder 具体建造者:

public class ConcreteProduct extends Builder{
    private Product product = new Product();
    @Override
    void setPart() {
        // 独特的处理逻辑
    }

    @Override
    Product buildProduct() {
        return product;
    }
}

Director 导演类:

public class Director {
    private Builder builder = new ConcreteProduct();
    public Product getProduct() {
        builder.setPart();
        // 设置不同的 part ,生产不同的零件
        return builder.buildProduct();
    }
}

3. 通过建造者模式造一辆共享单车

接下来使用建造者模式造一辆共享单车。

经历过共享单车大战之后,现在共享单车还在运营活着的也没几家了,在大街上比较常看到的有美团单车和哈罗单车,先创建一个抽象的产品类:

public abstract class AbstractBike {
    // 各个零件制造顺序
    private ArrayList<String> sequence = new ArrayList<> ();
    // 自行车车架
    protected abstract void frame();
    // 自行车座位
    protected abstract void seat();
    // 自行车轮子
    protected abstract void tire();
    // 生产方法
    final public void createBike() {
        for (int i = 0; i < sequence.size(); i++) {
            String actionName = this.sequence.get(i);
            if (actionName.equalsIgnoreCase("frame")) {
                this.frame();
            } else if (actionName.equalsIgnoreCase("seat")) {
                this.seat();
            } else if (actionName.equalsIgnoreCase("tire")) {
                this.tire();
            }
        }
    }

    final public void setSequence(ArrayList sequence) {
        this.sequence = sequence;
    }
}

在这个产品类中,定义了三个零件和一个零件的制造顺序,在单车的生产方法中,通过循环制造顺序,可以制造的顺序进行控制。

接下来是两个具体的产品类:

public class HelloBike extends AbstractBike {
    @Override
    protected void frame() {
        System.out.println("现在开始生产一个哈罗车架");
    }

    @Override
    protected void seat() {
        System.out.println("现在开始生产一个哈罗座位");
    }

    @Override
    protected void tire() {
        System.out.println("现在开始生产两个哈罗轮胎");
    }
}

public class MeituanBike extends AbstractBike {
    @Override
    protected void frame() {
        System.out.println("现在开始生产一个美团车架");
    }

    @Override
    protected void seat() {
        System.out.println("现在开始生产一个美团座位");
    }

    @Override
    protected void tire() {
        System.out.println("现在开始生产两个美团轮胎");
    }
}

接下来创建一个抽象的 Builder :

public abstract class Builder {
    // 创建一个生产顺序模型
    public abstract void setSequence(ArrayList<String> sequence);
    // 生产完成后获取这个车辆模型
    public abstract AbstractBike getBike();
}

然后是两个具体的建造者:

public class HelloBuilder extends Builder {
    private HelloBike helloBike = new HelloBike();
    @Override
    public void setSequence(ArrayList<String> sequence) {
        this.helloBike.setSequence(sequence);
    }

    @Override
    public AbstractBike getBike() {
        return this.helloBike;
    }
}

public class MeituanBuilder extends Builder {
    private MeituanBike meituanBike = new MeituanBike();
    @Override
    public void setSequence(ArrayList<String> sequence) {
        this.meituanBike.setSequence(sequence);
    }

    @Override
    public AbstractBike getBike() {
        return this.meituanBike;
    }
}

最后是一个导演类:

public class Director {
    private ArrayList<String> sequence = new ArrayList<>();
    private HelloBuilder helloBuilder = new HelloBuilder();
    private MeituanBuilder meituanBuilder = new MeituanBuilder();

    public HelloBike getHelloBike() {
        this.sequence.clear();
        // 自定义生产的顺序
        this.sequence.add("frame");
        this.sequence.add("seat");
        this.sequence.add("tire");
        this.helloBuilder.setSequence(sequence);
        return (HelloBike) this.helloBuilder.getBike();
    }

    public MeituanBike getMeituanBike() {
        this.sequence.clear();
        // 定义生产的顺序
        this.sequence.add("seat");
        this.sequence.add("tire");
        this.sequence.add("frame");
        this.meituanBuilder.setSequence(sequence);
        return (MeituanBike) this.meituanBuilder.getBike();
    }
}

然后写一个 Test 类进行一下测试:

public class Test {
    public static void main(String[] args) {
        Director director = new Director();
        director.getHelloBike().createBike();
    }
}

运行结果是:

现在开始生产一个哈罗车架
现在开始生产一个哈罗座位
现在开始生产两个哈罗轮胎

最后放一个这个示例的 UML 类图: