努力保头发的打工人
努力保头发的打工人
发布于 2020-12-12 / 18 阅读 / 0 评论 / 0 点赞

建造者模式

1 概述

1.1 定义

将一个复杂对象的构建和它的表示分离,使得同样的构建过程可以创建不同的表示。

1.2 通用类图

建造者模式类图.png

  • product类是要建造的产品,一般是使用了模板方法模式,也就是有模板方法和基本方法。

  • builderl类为抽象建造者,规范产品的组建,一般由子类实现。

  • concrebuilder为具体建造者,实现抽象类中的所有方法,并返回一个组建好的对象。

  • director导演类,负责安排已有模块的顺序。需要什么产品,什么具体顺序要求在这里定义。

说明:建造者模式强调的是基本方法的调用顺序。

1.3 优点
  • 封装性好:客户端不知道产品组成细节。

  • 建造者独立,容易扩展:每个建造者之间相互独立。

  • 便于控制风险:每个建造者控制对应产品,不会对其他产生影响。

1.4使用场景
  • 相同方法,不同的执行顺序,产生不同时间结果时;

  • 多个部件或零件都可以装配到一个对象中,但是产生的运行结果又不相同时;

  • 产品非常复杂,或产品类中的调用顺序不同产生不同的效能时;

  • 在对象创建过程中会使用到系统中的一些其他对象,这些对象在产品对象的创建过程中不易得到时;

2 示例代码

首先创建产品抽象类和产品:

/**
 * @author chiangtaol
 * @date 2020-11-26
 * @describe 汽车模型抽象类
 */
public abstract class CarModel {
​
    private List<CarFunction> sequence = new ArrayList<>();
​
    /**
     * 汽车启动
     */
    abstract void start();
​
    /**
     * 汽车停止
     */
    abstract void stop();
​
    /**
     * 喇叭
     */
    abstract void alarm();
​
    /**
     * 声浪
     */
    abstract void voice();
​
    /**
     * 模型功能的顺序
     * @param sequence 自定义的顺序
     */
    final public void setSequence(ArrayList<CarFunction> sequence){
        this.sequence = sequence;
    }
​
    /**
     * 建造模型
     */
    final public void run(){
        for (CarFunction function : this.sequence){
            switch (function){
                case START:
                    this.start();
                    break;
                case STOP:
                    this.stop();
                    break;
                case ALARM:
                    this.alarm();
                    break;
                case VOICE:
                    this.voice();
                    break;
                default:
                    System.out.println("俺不信能走到这里!!!");
                    break;
            }
        }
    }
}
​
/**
 * @author chiangtaol
 * @date 2020-11-27
 * @describe 奔驰模型实现类
 */
public class BenzModel extends CarModel {
    /**
     * 汽车启动
     */
    @Override
    void start() {
        System.out.println("奔驰这样启动...");
    }
​
    /**
     * 汽车停止
     */
    @Override
    void stop() {
        System.out.println("奔驰这样停止...");
    }
​
    /**
     * 喇叭
     */
    @Override
    void alarm() {
        System.out.println("奔驰这样响的...");
    }
​
    /**
     * 声浪
     */
    @Override
    void voice() {
        System.out.println("奔驰声浪是这样的...");
    }
}

然后定义建造者和其实现类

/**
 * @author chiangtaol
 * @date 2020-11-27
 * @describe 汽车模型建造抽象类
 */
public abstract class CarBuilder {
​
    public abstract void  setSequence(ArrayList<CarFunction> sequence);
​
    public abstract CarModel getCar();
}
​
/**
 * @author chiangtaol
 * @date 2020-11-27
 * @describe 奔驰模型建造者
 */
public class BenzBuilder extends CarBuilder{
​
    private BenzModel benzModel= new BenzModel();
​
    @Override
    public void setSequence(ArrayList<CarFunction> sequence) {
        this.benzModel.setSequence(sequence);
    }
​
    @Override
    public CarModel getCar() {
        return this.benzModel;
    }
}

最后定义导演类来开始定义产品功能的顺序,其中宝马类和奔驰类似,不再贴出。

/**
 * @author chiangtaol
 * @date 2020-11-27
 * @describe 模型功能
 */
public enum CarFunction {
        START,
        STOP,
        ALARM,
        VOICE;
}
​
​
/**
 * @author chiangtaol
 * @date 2020-11-27
 * @describe 模型定义类
 */
public class Director {
​
    private ArrayList<CarFunction> list = new ArrayList<>();
​
    private CarBuilder builderBWM = new BWMBuilder();
    private CarBuilder builderBenz = new BenzBuilder();
​
    /**
     * 宝马模型1,只会启动停止
     * @return /
     */
    public CarModel getBWMModel1(){
        list.clear();
        list.add(CarFunction.START);
        list.add(CarFunction.STOP);
        builderBWM.setSequence(list);
        return builderBWM.getCar();
    }
​
    /**
     * 宝马模型2,功能全都有
     * @return
     */
    public CarModel getBWMModel2(){
        list.clear();
        list.add(CarFunction.START);
        list.add(CarFunction.ALARM);
        list.add(CarFunction.VOICE);
        list.add(CarFunction.STOP);
        builderBWM.setSequence(list);
        return builderBWM.getCar();
    }
​
    /**
     * 奔驰模型1,只会启动停止
     * @return /
     */
    public CarModel getBenzModel1(){
        list.clear();
        list.add(CarFunction.START);
        list.add(CarFunction.STOP);
        builderBenz.setSequence(list);
        return builderBenz.getCar();
    }
​
    /**
     * 奔驰模型2,功能全都有
     * @return
     */
    public CarModel getBenzModel2(){
        list.clear();
        list.add(CarFunction.START);
        list.add(CarFunction.ALARM);
        list.add(CarFunction.VOICE);
        list.add(CarFunction.STOP);
        builderBenz.setSequence(list);
        return builderBenz.getCar();
    }
​
}

调用方就可以直接调用想要产品的对应方法即可,完全屏蔽产品内部细节

/**
 * @author chiangtaol
 * @date 2020-11-27
 * @describe
 */
class DirectorTest {
​
    @Test
    void getModel() {
        // 创建导演类
        Director director = new Director();
​
        // 得到指定产品并运行
        director.getBenzModel1().run();
        System.out.println("---------------------");
        director.getBenzModel2().run();
        
        System.out.println("=====================");
        
        director.getBWMModel1().run();
        System.out.println("---------------------");
        director.getBWMModel2().run();
    }
}
//结果如下
奔驰这样启动...
奔驰这样停止...
---------------------
奔驰这样启动...
奔驰这样响的...
奔驰声浪是这样的...
奔驰这样停止...
=====================
宝马这样启动...
宝马这样停止...
---------------------
宝马这样启动...
宝马这样响...
宝马声浪是这样的...
宝马这样停止...