Builder Patterns

GoF定义:将复杂对象的初始化过程根据它的参数来做拆分,这样一个构造过程可以构造出不同的对象(属性内容不同)

概念

在一个复杂对象的构造过程中,如果它状态的组成部分是相互独立的,那么可以使用这个模式。这种构造过程可以按照需要创建出不同的对象

例子

现实世界:当组装一台电脑时,它的零部件在每一个部分都可以是不同的(AMD CPU+AMD GPU、Intel CPU+NV GPU)
代码世界:将一种文本格式转变为另一种文本格式(不同的文本格式创建不同的对象)

展示

这里,Car和Motorcycle都实现了IBuilder接口,IBuilder是用来创建Product对象的一部分,而Product就代表一个复杂对象。装配产品的过程定义在Product中(使用了LinkedList的数据结构来表示装配过程)。接口中前三个接口来把机器的组成部分创建好,最后的getVehicle方法返回最终的产品,最后,Director负责构建最终的机器。Director会使用IBuilder来制造产品,它会调用不同的construct方法来构造不同类型的机器

代码

public class BuilderPatternEx {

    public static void main(String[] args) {
        Director director = new Director();

        IBuilder carBuilder = new Car();
        IBuilder motorcycleBuilder = new Motorcycle();

        director.construct(carBuilder);
        Product car = carBuilder.getVehicle();
        car.show();

        director.construct(motorcycleBuilder);
        Product motorcycle = motorcycleBuilder.getVehicle();
        motorcycle.show();
    }
}

interface IBuilder {
    void buildBody();
    void insertWheels();
    void addHeadLights();
    Product getVehicle();
}

class Car implements IBuilder {

    private Product product = new Product();

    @Override
    public void buildBody() {
        product.add("This is a body of a Car");
    }

    @Override
    public void insertWheels() {
        product.add("4 wheels are added");
    }

    @Override
    public void addHeadLights() {
        product.add("2 Headlights are added");
    }

    @Override
    public Product getVehicle() {
        return product;
    }
}

class Motorcycle implements IBuilder {

    private Product product = new Product();

    @Override
    public void buildBody() {
        product.add("This is a body of a Motorcycle");
    }

    @Override
    public void insertWheels() {
        product.add("2 wheels are added");
    }

    @Override
    public void addHeadLights() {
        product.add("1 Headlights are added");
    }

    @Override
    public Product getVehicle() {
        return product;
    }
}

class Product {
    private LinkedList<String> parts;

    public Product() {
        this.parts = new LinkedList<>();
    }

    public void add(String part) {
        this.parts.addLast(part);
    }

    public void show() {
        System.out.println("\nProduct completed as below :");
        for (String part: parts) {
            System.out.println(part);
        }
    }
}

class Director {
    IBuilder iBuilder;

    public void construct(IBuilder iBuilder) {
        this.iBuilder = iBuilder;
        iBuilder.buildBody();
        iBuilder.insertWheels();
        iBuilder.addHeadLights();
    }
}

Note

  1. 这里创建一个最终对象(Product)的过程被隐藏到了Director中
  2. 关注点在于“product是怎么被制作出来的”
  3. 通常,只有一个方法来返回最终需要的对象,其它的方法都是做部分工作
  4. 需要一些重复代码(缺点)。因为不同类型可能会有一些相同的构造过程(现在接口可以实现默认方法,感觉弥补了)
  5. 如果我们需要一个mutable的对象,那么不应该使用这个模式(没必要)

思考

这个Builder模式其实就是将复杂对象的构造过程抽象出来做了一个构造过程的接口(IBuilder),这个类首先得是一个意义上的超类(汽车和摩托车都是产品,这里如果有继承关系也是可以的),通过对它的构造过程的实现来创建出不同类型的对象。构造过程封装到Director类中,也可以在这里做一些自定义的操作

posted on 2020-12-06 16:52  老鼠不上树  阅读(96)  评论(0)    收藏  举报