java设计模式--建造者模式

首先我们先看一个例子,假设我们要生产CarA,CarB

public class CarA {

    public void makeWheels(){
        System.out.println("制造CarA的轮子");
    }

    public void makeCarBody(){
        System.out.println("制造车CarA车身");
    }

    public void sprayPaint(){
        System.out.println("给CarA喷漆");
    }

    public void build(){
        makeWheels();
        makeCarBody();
        sprayPaint();
    }
}
public class CarB {
    public void makeWheels(){
        System.out.println("制造CarB的轮子");
    }

    public void makeCarBody(){
        System.out.println("制造车CarB车身");
    }

    public void sprayPaint(){
        System.out.println("给CarB喷漆");
    }

    public void build(){
        makeWheels();
        makeCarBody();
        sprayPaint();
    }
}
public class Test {
    public static void main(String[] args) {
        CarA carA = new CarA();
        carA.build();

        CarB carB = new CarB();
        carB.build();
    }
}

结果:

制造CarA的轮子
制造车CarA车身
给CarA喷漆
制造CarB的轮子
制造车CarB车身
给CarB喷漆

  从上面的例子我们可以看到CarA和CarB有相同的构造过程,都需要造轮子,车身,喷漆,这个流程是“稳定的”,但是具体实现的细节是不同的,假设我们现在需要新增一个CarC类,那么就需要重新再实现一遍上述的流程,在实现的过程中存在出错的可能(CarC创建时缺少部分部件的创建方法),并且客户端还需要知道产品的创建过程(导致耦合度高),此时我们就可以使用建造者模式,此时用户只需要指定构造的类型,而不需要了解细节。

建造者模式:将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。下面我们来看建造者模式下的例子

汽车类,由多个部件组成

//产品类
public class Car {

    List<String> list = new ArrayList<>();

    //添加Car的部件
    public void build(String string){
        list.add(string);
    }

    //展示所有产品部件
    public void show(){
        for(String string : list){
            System.out.println(string);
        }
    }

}

 

Builder接口,定义汽车由三个部件组成,以及一个展示汽车的方法。

//Builder接口,定义制造汽车的步骤
public interface Builder {

    void makeWheels();

    void makeCarBody();

    void sprayPaint();

    //定义展示Car的方法
    Car showCar();

}
//具体的建造类A
public class BuildCarA implements Builder {

    Car car = new Car();

    @Override
    public void makeWheels() {
        car.build("制造CarA的轮子");
    }

    @Override
    public void makeCarBody() {
        car.build("制造车CarA车身");
    }

    @Override
    public void sprayPaint() {
        car.build("给CarA喷漆");
    }

    @Override
    public Car showCar() {
         return car;
    }
}
//具体的建造类B
public class BuildCarB implements Builder {

    Car car = new Car();

    @Override
    public void makeWheels() {
        car.build("制造CarB的轮子");
    }

    @Override
    public void makeCarBody() {
        car.build("制造车CarB车身");
    }

    @Override
    public void sprayPaint() {
        car.build("给CarB喷漆");
    }

    @Override
    public Car showCar() {
        return car;
    }
}

 

Director类,指挥者类,客户端通过此类来建造产品而无需知道细节。

//指挥者类 用来指挥建造过程
public class Director {
    public void Construct(Builder builder){
        builder.makeWheels();
        builder.makeCarBody();
        builder.sprayPaint();
    }
}

 

测试类 

public class Test2 {
    public static void main(String[] args) {
        Director director = new Director();
        Builder buildCarA = new BuildCarA();
        Builder buildCarB = new BuildCarB();

        //通过指挥者来建造产品
        director.Construct(buildCarA);
        Car carA = buildCarA.showCar();
        carA.show();

        director.Construct(buildCarB);
        Car carB = buildCarB.showCar();
        carB.show();
    }
}

测试结果:

制造CarA的轮子
制造车CarA车身
给CarA喷漆
制造CarB的轮子
制造车CarB车身
给CarB喷漆

  总结:对于创建过程复杂,并且创建过程由客户端控制(此设计问题见Test),每次客户端创建产品时都会使用重复操作(此设计问题见Test),并有可能缺少步骤(通过建造者模式的Builder接口避免此情况),或者产品对象是可变化时(见BuildCarA,BuildCarB,),我们可以使用建造者模式。通过这种模式使客户端和产品分离,创建内部构建方法稳定,但是实现细节不同的对象。

点赞