有两种建造者模式
- 有导演类(场景:消费者从不同的方案中选择一个方案获取目标产物)
- 无导演类(场景:消费者DIY获取目标产物)
有导演类
代码文件如下
- 目标产物的定义
public class Car {
private String tire;
private String window;
private String light;
private String trumpet;
public String getTire() {
return tire;
}
public void setTire(String tire) {
this.tire = tire;
}
public String getWindow() {
return window;
}
public void setWindow(String window) {
this.window = window;
}
public String getLight() {
return light;
}
public void setLight(String light) {
this.light = light;
}
public String getTrumpet() {
return trumpet;
}
public void setTrumpet(String trumpet) {
this.trumpet = trumpet;
}
@Override
public String toString() {
return "Car{" +
"tire='" + tire + ''' +
", window='" + window + ''' +
", light='" + light + ''' +
", trumpet='" + trumpet + ''' +
'}';
}
}
2.定义方案的内容
/**
* 抽象的建造者:方法
*/
public abstract class Builder {
public abstract void buildTire(); // 装轮胎
public abstract void buildWindow(); // 装窗户
public abstract void buildLight(); // 装大灯
public abstract void buildTrumpet(); // 装喇叭
// 完工:得到车子
public abstract Car getCar();
}
3.使用统一的方案,给到不同的厂家,设置不同的目标产物的内容
/**
* 具体的建造者:工人
*/
public class FerrariWorker extends Builder {
private Car car;
public FerrariWorker() {
this.car = new Car();
}
@Override
public void buildTire() {
this.car.setTire("法拉利装轮胎");
System.err.println("法拉利装轮胎");
}
@Override
public void buildWindow() {
this.car.setWindow("法拉利装窗户");
System.err.println("法拉利装窗户");
}
@Override
public void buildLight() {
this.car.setLight("法拉利装大灯");
System.err.println("法拉利装大灯");
}
@Override
public void buildTrumpet() {
this.car.setTrumpet("法拉利装喇叭");
System.err.println("法拉利装喇叭");
}
@Override
public Car getCar() {
return this.car;
}
}
/**
* 具体的建造者:工人
*/
public class PorscheWorker extends Builder {
private Car car;
public PorscheWorker() {
car = new Car();
}
@Override
public void buildTire() {
car.setTire("保时捷装轮胎");
System.err.println("保时捷装轮胎");
}
@Override
public void buildWindow() {
car.setWindow("保时捷装窗户");
System.err.println("保时捷装窗户");
}
@Override
public void buildLight() {
car.setLight("保时捷装大灯");
System.err.println("保时捷装大灯");
}
@Override
public void buildTrumpet() {
car.setTrumpet("保时捷装喇叭");
System.err.println("保时捷装喇叭");
}
@Override
public Car getCar() {
return this.car;
}
}
4.指挥者(导演类)给定不同的建造顺序
/**
* 指挥:核心。负责指挥构建一个工程,按什么顺序构建工程由它决定
*/
public class Director {
/**
* 顺序装车
*/
public Car ascBuildCar(Builder builder) {
builder.buildTire();
builder.buildWindow();
builder.buildLight();
builder.buildTrumpet();
return builder.getCar();
}
/**
* 倒序装车
*/
public Car descBuildCar(Builder builder) {
builder.buildTrumpet();
builder.buildLight();
builder.buildWindow();
builder.buildTire();
return builder.getCar();
}
}
5.指挥者(导演类 Director)指挥不同的建造者(Worker)按指挥顺序进行建造
public class test {
/**
* 常规用法,指挥者(导演类 Director)指挥不同的建造者(Worker)按指挥顺序进行建造
*/
public static void main(String[] args) {
Director director = new Director();
Car ascPorsche = director.ascBuildCar(new PorscheWorker());
System.err.println(ascPorsche.toString());
Car descPorsche = director.descBuildCar(new PorscheWorker());
System.err.println(descPorsche.toString());
Car ascFerrari = director.ascBuildCar(new FerrariWorker());
System.err.println(ascFerrari.toString());
Car descFerrari = director.descBuildCar(new FerrariWorker());
System.err.println(descFerrari.toString());
}
}
输出结果如下
保时捷装轮胎
保时捷装窗户
保时捷装大灯
保时捷装喇叭
Car{tire='保时捷装轮胎', window='保时捷装窗户', light='保时捷装大灯', trumpet='保时捷装喇叭'}
保时捷装喇叭
保时捷装大灯
保时捷装窗户
保时捷装轮胎
Car{tire='保时捷装轮胎', window='保时捷装窗户', light='保时捷装大灯', trumpet='保时捷装喇叭'}
法拉利装轮胎
法拉利装窗户
法拉利装大灯
法拉利装喇叭
Car{tire='法拉利装轮胎', window='法拉利装窗户', light='法拉利装大灯', trumpet='法拉利装喇叭'}
法拉利装喇叭
法拉利装大灯
法拉利装窗户
法拉利装轮胎
Car{tire='法拉利装轮胎', window='法拉利装窗户', light='法拉利装大灯', trumpet='法拉利装喇叭'}
无导演类
代码文件如下
- 目标产物的定义,并允许给到默认值
public class Car {
private String tire = "tireOne";
private String window = "windowOne";
private String light = "lightOne";
private String trumpet = "trumpetOne";
public String getTire() {
return tire;
}
public void setTire(String tire) {
this.tire = tire;
}
public String getWindow() {
return window;
}
public void setWindow(String window) {
this.window = window;
}
public String getLight() {
return light;
}
public void setLight(String light) {
this.light = light;
}
public String getTrumpet() {
return trumpet;
}
public void setTrumpet(String trumpet) {
this.trumpet = trumpet;
}
@Override
public String toString() {
return "Car{" +
"tire='" + tire + ''' +
", window='" + window + ''' +
", light='" + light + ''' +
", trumpet='" + trumpet + ''' +
'}';
}
}
2.定义方案的内容,并允许消费者设定方案
public abstract class Builder {
public abstract Builder buildTire(String tire); // 装轮胎
public abstract Builder buildWindow(String window); // 装窗户
public abstract Builder buildLight(String light); // 装大灯
public abstract Builder buildTrumpet(String trumpet); // 装喇叭
// 完工:得到车子
public abstract Car getCar();
}
3.工人根据消费者的内容进行目标产物的设置
public class Worker extends Builder {
private Car car;
public Worker() {
car = new Car();
}
@Override
public Builder buildTire(String tire) {
car.setTire(tire);
return this;
}
@Override
public Builder buildWindow(String window) {
car.setWindow(window);
return this;
}
@Override
public Builder buildLight(String light) {
car.setLight(light);
return this;
}
@Override
public Builder buildTrumpet(String trumpet) {
car.setTrumpet(trumpet);
return this;
}
@Override
public Car getCar() {
return this.car;
}
}
4.最终消费者DIY建造
/**
* 无导演类
* 场景:麦当劳点套餐,默认有一个套餐内容,消费者可以选择更改套餐里的食物
*/
public class test {
public static void main(String[] args) {
Car carOne = new Worker().getCar();
System.err.println(carOne.toString());
// 链式编程,在原来的基础上允许自由组合,如果不组合,也有默认值
Car carTwo = new Worker().buildTire("tireTwo").buildTrumpet("trumpetTwo").getCar();
System.err.println(carTwo.toString());
}
}
输出结果如下
Car{tire='tireOne', window='windowOne', light='lightOne', trumpet='trumpetOne'}
Car{tire='tireTwo', window='windowOne', light='lightOne', trumpet='trumpetTwo'}