2、11建造者/生成器模式
定义
建造者模式也叫做生成器模式。
1)将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
2)建造者模式可以将一个产品的内部表象与产品的生成过程分割开来,从而可以使一个建造过程生成具有不同的内部表象的产品对象。如果我们用了建造者模式,那么用户就只需指定需要建造的类型就可以得到它们,而具体建造的过程和细节就不需要知道了。
通用类图
案例
public class Client1 {
public static void main(String[] args) {
}
}
/**
* 产品类
* 如果有多个产品类就有几个具体的建造者,而且这多个产品类具有相同接口或抽象类.z
*/
class Product{
public void doSomething(){
//独立业务处理
}
}
/**
* 抽象建造者
* 如果有多个产品类就有几个具体的建造者,而且这多个产品类具有相同接口或抽象类.z
*/
abstract class Builder{
//设置产品的不同部分,以获得不同的产品
public abstract void setPart();
//建造产品
public abstract Product buildProduct();
}
/**
* 具体建造者
*/
class ConcreteBuilder extends Builder{
private Product product = new Product();
//设置产品零件
@Override
public void setPart() {
//产品类内的逻辑处理
}
//组件一个产品
@Override
public Product buildProduct() {
return product;
}
}
/**
* 导演类
*/
class Director{
private Builder builder = new ConcreteBuilder();
//构建不同的产品
public Product getProduct(){
builder.setPart();
//设置不同的零件,产生不同的产品
return builder.buildProduct();
}
}
场景案例(汽车)
public class Client2 {
public static void main(String[] args) {
Director director = new Director();
for (int i = 0; i < 2; i++) {
director.getBenzModel().run();
System.out.println("-------------------");
}
System.out.println("====================");
for (int i = 0; i < 2; i++) {
director.getBMWModel().run();
System.out.println("-------------------");
}
}
}
/**
* 车辆模型的抽象类
*/
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 < this.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<String> sequence){
this.sequence = sequence;
}
}
/**
* 奔驰车模型
*/
class BenzModel extends CarModel{
@Override
protected void start() {
System.out.println("奔驰..........start");
}
@Override
protected void stop() {
System.out.println("奔驰..........stop");
}
@Override
protected void alarm() {
System.out.println("奔驰..........alarm");
}
@Override
protected void engineBoom() {
System.out.println("奔驰..........engineBoom");
}
}
/**
* 宝马车模型
*/
class BMWModel extends CarModel{
@Override
protected void start() {
System.out.println("宝马..........start");
}
@Override
protected void stop() {
System.out.println("宝马..........stop");
}
@Override
protected void alarm() {
System.out.println("宝马..........alarm");
}
@Override
protected void engineBoom() {
System.out.println("宝马..........engineBoom");
}
}
/**
* 抽象汽车组转者
*/
abstract class CarBuilder{
//建造一个模型,安装给定的顺序来组装
public abstract void setSequence(ArrayList<String> sequence);
//设置完顺序后,可以直接拿到这个车辆模型
public abstract CarModel getCarModel();
}
/**
* 奔驰车组装者
*/
class BenzBuilder extends CarBuilder{
private BenzModel model = new BenzModel();
@Override
public void setSequence(ArrayList<String> sequence) {
this.model.setSequence(sequence);
}
@Override
public CarModel getCarModel() {
return this.model;
}
}
/**
* 宝马车组装者
*/
class BMWBuilder extends CarBuilder{
private BMWModel model = new BMWModel();
@Override
public void setSequence(ArrayList<String> sequence) {
this.model.setSequence(sequence);
}
@Override
public CarModel getCarModel() {
return this.model;
}
}
/**
* 导演类
* 指挥各个事件的先后顺序
*/
class Director{
private ArrayList<String> sequence = new ArrayList<>();
private BenzBuilder benzBuilder = new BenzBuilder();
private BMWBuilder bmwBuilder = new BMWBuilder();
/**
* 奔驰车某类模型
* @return
*/
public BenzModel getBenzModel(){
//这里可能会引起数据混乱,只是作为案例使用,清理场景,这里一定要注意
this.sequence.clear();
//设置执行顺序
this.sequence.add("start");
this.sequence.add("stop");
//按顺序返回一辆奔驰
this.benzBuilder.setSequence(this.sequence);
return (BenzModel) this.benzBuilder.getCarModel();
}
/**
* 宝马车某类模型
* @return
*/
public BMWModel getBMWModel(){
//这里可能会引起数据混乱,只是作为案例使用,清理场景,这里一定要注意
this.sequence.clear();
//设置执行顺序
this.sequence.add("engineBoom");
this.sequence.add("alarm");
this.sequence.add("start");
this.sequence.add("stop");
//按顺序返回一辆宝马
this.bmwBuilder.setSequence(this.sequence);
return (BMWModel) this.bmwBuilder.getCarModel();
}
}
奔驰..........start
奔驰..........stop
-------------------
奔驰..........start
奔驰..........stop
-------------------
====================
宝马..........engineBoom
宝马..........alarm
宝马..........start
宝马..........stop
-------------------
宝马..........engineBoom
宝马..........alarm
宝马..........start
宝马..........stop
-------------------
优点
1)封装性
使用建造者模式可以使客户端不必知道产品内部组成的细节。
2)建造者独立,容易扩展。
3)便于控制细节风险
由于具体的建造者是独立的,因此可以对建造过程逐步细化,而不对其他的模块产生任何影响。
4)允许对象通过多个步骤来创建,并且可以改变过程(这和只有一个步骤的工厂模式不同)。
5)产品的实现可以被替换,因为客户只看到一个抽象的接口。
使用场景
1)相同的方法,不同的执行顺序,产生不同的事件结果时,可以采用建造者模式。
2)多个部件或零件,都可以装配到一个对象中,但是产生的运行结果又不相同时,则可以使用建造者模式。
3)产品类非常复杂,或者产品类中的调用顺序不同产生了不同的效能,这个时候使用建造者模式非常合适。
4)在对象创建过程中会使用到系统中的一些其他对象,这些对象在产品对象的创建过程中不易得到时,也可以采用建造者模式封装该对象的创建过程。该场景只能是一个补偿方法,因为一个对象不容易获得,而在设计阶段竟然没有发觉,而要通过创建者模式柔化创建过程,本身已经违反了设计的最初目标。
5)经常被用来创建组合结构。
注意事项
建造者模式关注的是零件类型和装配工艺(顺序),这是它与工厂方法模式最大不同的地方,虽然同为创建类模式,但是注重点不同。
建造者模式最主要的功能是基本方法的调用顺序安排,也就是这些基本方法已经实现了,通俗地说就是零件的装配,顺序不同产生的对象也不同;而工厂方法则重点是创建,创建零件是它的主要职责,组装顺序则不是它关心的。
标题:设计模式(十一)创建型模式(对象创建型模式)生成器/建造者-BUILDER
作者:yazong
地址:https://blog.llyweb.com/articles/2020/07/01/1593613157760.html