设计模式系列——建造者模式

372 阅读3分钟

原创:花括号MC(微信公众号:huakuohao-mc),欢迎分享,转载请保留出处。

建造者模式用于将复杂对象的创建和表示分离,有些对象由很多部分组成,每个部分又可以有多种不同选择,创建这种对象的时候往往需要考虑使用建造者模式。

举个例子

一辆汽车由发动机,方向盘,车灯,车灯,车身颜色等组成,每辆车的颜色,车轮大小,车灯样式可能会不一样,但是车的组成部分不会少。

建造模式有两种实现方式,第一种方式是有导演的方式,第二种是无导演方式。根据我的经验日常使用无导演的方式可能会更多一些。

有导演

所谓有导演就是通过一个导演类来指挥对象创建的过程,客户端使用导演类来获取对象,不用关心对象具体的创建过程。

先看一下UML图,对建造模式有个大概的了解。

builder-director.png

看一下具体代码,我们以建造一辆汽车举例

public class Car {

    private String wheel;
    private String engine;
    private String seat;
    private String lamp;
    private String color;

   //篇幅原因,此处省略get,set方法

    @Override
    public String toString() {
        return "Car{" +
                "wheel='" + wheel + ''' +
                ", engine='" + engine + ''' +
                ", seat='" + seat + ''' +
                ", lamp='" + lamp + ''' +
                ", color='" + color + ''' +
                '}';
    }
}

抽象Builder类,指定建造复杂对象步骤

public abstract class Builder {
    
    public abstract void buildWheel();

    public abstract void buildSeat();

    public abstract void buildLamp();

    public abstract void buildColor();

    public abstract void buildEngine();

    public abstract Car getCar();

}

具体Builder类,实现复杂对象具体建造过程和内容

public class ConcreteBuilder extends Builder {

    private Car car;

    public ConcreteBuilder() {
        car = new Car();
    }

    @Override
    public void buildWheel() {
        car.setWheel("wheel");
    }

    @Override
    public void buildSeat() {
        car.setSeat("seat");
    }

    @Override
    public void buildLamp() {
        car.setLamp("lamp");
    }

    @Override
    public void buildColor() {
        car.setColor("color");
    }

    @Override
    public void buildEngine() {
        car.setEngine("engine");
    }

    //返回构建好的汽车模型
    @Override
    public Car getCar() {
        return car;
    }
}

Director类,决定了复杂对象的创建过程。

public class CarDirector {
    public Car createCar(Builder builder){
        builder.buildWheel();
        builder.buildSeat();
        builder.buildLamp();
        builder.buildColor();
        builder.buildEngine();
        return builder.getCar();
    }
}

客户端这样使用

public class BuilderClient {
    public static void main(String[] args){
        CarDirector carDirector = new CarDirector();
        //通过Director创建具体对象,不关心对象的创建过程
        Car car = carDirector.createCar(new ConcreteBuilder());
        System.out.println(car.toString());
    }
}

无导演

无导演模式感觉日常开发中用的比较多,但凡见到形似这样的代码,大概率就是建造者模式了。

Car car = concreteBuilderA.buildEngine("engine")
                    .buildLamp("lamp")
                    .buildSeat("seat")
                    .buildColor("color")
                    //.buildWheel("wheel")
                    .build();

老规矩先来看一下UML图,来个整体的认识。

builder-without-director.png

同样来看一下具体代码实现,还是以创建汽车为例,所以Car的代码不在重复给出。

Builder

public abstract class BuilderA {
    //返回builder自身
    abstract BuilderA buildWheel(String wheel);
    abstract BuilderA buildEngine(String engine);
    abstract BuilderA buildLamp(String lamp);
    abstract BuilderA buildSeat(String seat);
    abstract BuilderA buildColor(String color);
    abstract Car build();
}

具体Builder,负责对象的具体创建工作。

public class ConcreteBuilderA extends BuilderA  {

    private Car car;

    public ConcreteBuilderA() {
        car = new Car();
    }

    @Override
    BuilderA buildWheel(String wheel) {
        car.setWheel(wheel);
        return this;
    }

    @Override
    BuilderA buildEngine(String engine) {
        car.setEngine("engine");
        return this;
    }

    @Override
    BuilderA buildLamp(String lamp) {
        car.setLamp("lamp");
        return this;
    }

    @Override
    BuilderA buildSeat(String seat) {
        car.setSeat("seat");
        return this;
    }

    @Override
    BuilderA buildColor(String color) {
        car.setColor("color");
        return this;
    }

    @Override
    Car build() {
        return car;
    }
}

客户端这样使用

public class BuilderAClient {
    public static void main(String[] args){
        ConcreteBuilderA concreteBuilderA = new ConcreteBuilderA();

        Car car = concreteBuilderA.buildEngine("engine")
                    .buildLamp("lamp")
                    .buildSeat("seat")
                    .buildColor("color")
                    //.buildWheel("wheel")
                    .build();
        System.out.println(car.toString());
    }
}

总结

建造者模式是创建型模式之一,所谓的没有Director的模式,只不过是把建造过程留给了客户端,让使用者自己决定怎样创建对象。无Director模式的实现关键是Builder类里面构建每个组件的方法都是返回Builder自己。

推荐阅读

1. Java并发编程那些事儿(十)——最后的总结

2. 程序员应该掌握的常用网络问题定位工具

3. Awk这件上古神兵你会用了吗

4. 手把手教你搭建一套ELK日志搜索运维平台

原创:花括号MC(微信公众号:huakuohao-mc)。关注JAVA基础编程及大数据,注重经验分享及个人成长。