java设计模式之建造者模式

1、建造者模式也叫生成器模式,其定义如下:将一个复杂对象的构建与它的表示分离, 使得同样的构建过程可以创建不同的表示。

2、建造者模式通用类图如下:

3、建造者模式有如下4个角色:product产品类、builder抽象建造者、concreteBuilder具体建造者、director导演类。

相关代码如下:

产品类

import java.util.ArrayList;

/**
 * 车辆模型抽象类
 *
 */
public abstract class CarModel {

    //这个参数是各个基本方法执行的顺序
    private ArrayList<String> sequence = new ArrayList<>();
    //模型是启动开始跑了
    protected abstract void start();
    //能发动,还要能停下来,那才是真本事
    protected abstract void stop();
    //喇叭会出声音
    protected abstract void alarm();
    //引擎发动
    protected abstract void engineBoom();
    //模型动起来
    final public void run() {
        //循环一遍,谁在前,就先执行谁
        for (int i = 0; i < sequence.size(); i++) {
            String actionName = this.sequence.get(i);
            if ("start".equalsIgnoreCase(actionName)) {
                this.start();
            } else if ("stop".equalsIgnoreCase(actionName)) {
                this.stop();
            } else if ("alarm".equalsIgnoreCase(actionName)) {
                this.alarm();
            } else if ("engineBoom".equalsIgnoreCase(actionName)) {
                this.engineBoom();
            }
        }
    }
    
    final public void setSequence(ArrayList sequence) {
        this.sequence = sequence;
    }
    
}
/**
 * 奔驰车模型
 *
 */
public class BenzModel extends CarModel {

    @Override
    protected void start() {
        System.out.println("奔驰车启动。。。");
    }

    @Override
    protected void stop() {
        System.out.println("奔驰车停下。。。");
    }

    @Override
    protected void alarm() {
        System.out.println("奔驰车喇叭声。。。");
    }

    @Override
    protected void engineBoom() {
        System.out.println("奔驰车引擎声。。。");        
    }

}
/**
 * 宝马车模型
 *
 */
public class BMWModel extends CarModel {

    @Override
    protected void start() {
        System.out.println("宝马车启动。。。");
    }

    @Override
    protected void stop() {
        System.out.println("宝马车停下。。。");
    }

    @Override
    protected void alarm() {
        System.out.println("宝马车喇叭声。。。");
    }

    @Override
    protected void engineBoom() {
        System.out.println("宝马车引擎声。。。");        
    }

}

建造者

import java.util.ArrayList;

/**
 * 抽象汽车组装者
 *
 */
public abstract class CarBuilder {

    //建造一个模型,你要给我一个顺序要求,就是组装顺序
    public abstract void setSequence(ArrayList<String> sequence);
    //设置完毕顺序后,就可以直接拿到这个车辆模型
    public abstract CarModel getCarModel();
}
/**
 * 奔驰车组装者
 *
 */
public class BenzBuilder extends CarBuilder {
    
    private BenzModel benz = new BenzModel();

    @Override
    public void setSequence(ArrayList<String> sequence) {
        this.benz.setSequence(sequence);
    }

    @Override
    public CarModel getCarModel() {
        return this.benz;
    }

}
/**
 * 宝马车组装者
 *
 */
public class BMWBuilder extends CarBuilder {
    
    private BMWModel bmw = new BMWModel();

    @Override
    public void setSequence(ArrayList<String> sequence) {
        this.bmw.setSequence(sequence);
    }

    @Override
    public CarModel getCarModel() {
        return this.bmw;
    }

}

导演类

import java.util.ArrayList;

/**
 * 导演类
 *
 */
public class Director {

    private ArrayList<String> sequence = new ArrayList<>();
    private BenzBuilder benzBuilder = new BenzBuilder();
    private BMWBuilder bmwBuilder = new BMWBuilder();
    
    //A类型的奔驰车模型,先start,然后stop,其他什么引擎、喇叭一概没有
    public BenzModel getABenzModel() {
        //清理场景
        this.sequence.clear();
        //执行顺序
        this.sequence.add("start");
        this.sequence.add("stop");
        //按照顺序返回一个奔驰车
        this.benzBuilder.setSequence(this.sequence);
        return (BenzModel) this.benzBuilder.getCarModel();
    }
    
    //B类型的奔驰车模型,先发动引擎,然后启动,然后停止,没有喇叭
    public BenzModel getBBenzModel() {
        //清理场景
        this.sequence.clear();
        //执行顺序
        this.sequence.add("engineBoom");
        this.sequence.add("start");
        this.sequence.add("stop");
        //按照顺序返回一个奔驰车
        this.benzBuilder.setSequence(this.sequence);
        return (BenzModel) this.benzBuilder.getCarModel();
    }
    
    //C类型的宝马车模型,先按下喇叭,然后启动,然后停止
    public BMWModel getCBMWModel() {
        //清理场景
        this.sequence.clear();
        //执行顺序
        this.sequence.add("alarm");
        this.sequence.add("start");
        this.sequence.add("stop");
        //按照顺序返回一个奔驰车
        this.benzBuilder.setSequence(this.sequence);
        return (BMWModel) this.bmwBuilder.getCarModel();
    }
    
    //D类型的宝马车模型只有一个功能,就是跑
    public BMWModel getDBMWModel() {
        //清理场景
        this.sequence.clear();
        //执行顺序
        this.sequence.add("start");
        //按照顺序返回一个奔驰车
        this.benzBuilder.setSequence(this.sequence);
        return (BMWModel) this.bmwBuilder.getCarModel();
    }
    
    /**
     * 还有很多其他模型可以添加实现
     */
}

客户端

/**
 * 客户端
 *
 */
public class Client {

    public static void main(String[] args) {
        Director director = new Director();
        //1万辆A类型的奔驰车
        for(int i = 0; i < 10000; i++) {
            director.getABenzModel().run();
        }
        //100万辆B类型的奔驰车
        for(int i = 0; i < 1000000; i++) {
            director.getBBenzModel().run();
        }
        //1000万辆C类型的宝马车
        for(int i = 0; i < 10000000; i++) {
            director.getCBMWModel().run();
        }
    }
}

4、建造者模式优点

封装性:
使用建造者模式可以使客户端不必知道产品内部组成的细节, 如例子中我们就不需要关心每一个具体的模型内部是如何实现的, 产生的对象类型就是CarModel。

建造者独立, 容易扩展:
BenzBuilder和BMWBuilder是相互独立的, 对系统的扩展非常有利。

便于控制细节风险
由于具体的建造者是独立的, 因此可以对建造过程逐步细化, 而不对其他的模块产生任何影响。

5、建造者模式使用场景

相同的方法, 不同的执行顺序, 产生不同的事件结果时, 可以采用建造者模式。

多个部件或零件, 都可以装配到一个对象中, 但是产生的运行结果又不相同时, 则可以使用该模式。

6、与工厂模式区别

建造者模式最主要的功能是基本方法的调用顺序安排, 也就是这些基本方法已经实现了, 通俗地说就是零件的装配, 顺序不同产生的对象也不同; 而工厂方法则重点是创建, 创建零件是它的主要职责, 组装顺序则不是它关心的。

 

原文地址:https://www.cnblogs.com/st-learning/p/13071009.html