建造者模式是设计模式的一种,将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
1)builder:为创建一个产品对象的各个部件指定抽象接口。
2)ConcreteBuilder:实现Builder的接口以构造和装配该产品的各个部件,定义并明确它所创建的表示,并提供一个检索产品的接口。
3)Director:构造一个使用Builder接口的对象。
4)Product:表示被构造的复杂对象。ConcreteBuilder创建该产品的内部表示并定义它的装配过程,包含定义组成部件的类,包括将这些部件装配成最终产品的接口。
一、实现
(一)抽象产品
/**
* 汽车产品抽象类
* @author EX-SONGTIANXI001
*
*/
public abstract class CarModel {
// 定义一个有序的集合
private ArrayList<String> sequence = new ArrayList<String>();
final public void setSequence(ArrayList<String> sequence){
this.sequence = sequence;
}
// 启动
protected abstract void start();
// 停止
protected abstract void stop();
// 引擎发动
protected abstract void engineBoom();
final public void run(){
for(int i = 0; i < this.sequence.size(); i++){
String str = (String)sequence.get(i);
if("start".equals(str)){
this.start();
}else if("stop".equals(str)){
this.stop();
}else if("engineBoom".equals(str)){
this.engineBoom();
}else{
System.out.println("没有此功能:"+str);
}
}
}
}
(二)具体产品
/**
* 奔驰车具体产品
* @author EX-SONGTIANXI001
*
*/
public class BENZ extends CarModel{
// 启动
@Override
public void start(){
System.out.println("奔驰汽车启动");
};
// 停止
@Override
public void stop(){
System.out.println("奔驰汽车停止");
};
// 引擎发动
@Override
public void engineBoom(){
System.out.println("奔驰汽车引擎发动");
};
}
/**
* 宝马具体产品类
* @author EX-SONGTIANXI001
*
*/
public class BMW extends CarModel{
// 启动
@Override
public void start(){
System.out.println("宝马汽车启动");
};
// 停止
@Override
public void stop(){
System.out.println("宝马汽车停止");
};
// 引擎发动
@Override
public void engineBoom(){
System.out.println("宝马汽车引擎发动");
};
}
(三)抽象建造工具
/**
* 汽车产品建造工具抽象类
* @author EX-SONGTIANXI001
*
*/
public abstract class CarBuilder {
// 设置汽车制造的顺序
public abstract void setSequence(ArrayList<String> sequence);
// 顺序设置完毕后拿到汽车模型
public abstract CarModel getCarModel();
}
(四)具体建造工具
/**
* 宝马具体建造工具
* @author EX-SONGTIANXI001
*
*/
public class BMWBuilder extends CarBuilder{
private BMW bmw = new BMW();
@Override
public void setSequence(ArrayList<String> sequence){
this.bmw.setSequence(sequence);
}
@Override
public CarModel getCarModel(){
return this.bmw;
}
}
/**
* 奔驰具体建造工具
* @author EX-SONGTIANXI001
*
*/
public class BENZBuilder extends CarBuilder{
private BENZ benz = new BENZ();
@Override
public void setSequence(ArrayList<String> sequence){
this.benz.setSequence(sequence);
}
@Override
public CarModel getCarModel(){
return this.benz;
}
}
(五)建造者
/**
* 建造者
*
* @author EX-SONGTIANXI001
*
*/
public class Director {
// 汽车的顺序
private ArrayList<String> sequence = new ArrayList<String>();
// 宝马生产工厂
private BMWBuilder bmwBuilder = new BMWBuilder();
// 奔驰生产工厂
private BENZBuilder benzBuilder = new BENZBuilder();
// 生产宝马A型汽车
public BMW getBMWProductA(){
this.sequence.clear();
sequence.add("start");
sequence.add("stop");
sequence.add("engineBoom");
this.bmwBuilder.setSequence(sequence);
return (BMW)this.bmwBuilder.getCarModel();
}
// 生产宝马B型汽车
public BMW getBMWProductB(){
this.sequence.clear();
sequence.add("engineBoom");
sequence.add("stop");
sequence.add("start");
this.bmwBuilder.setSequence(sequence);
return (BMW)this.bmwBuilder.getCarModel();
}
// 生产奔驰A型汽车
public BENZ getBENZProductA(){
this.sequence.clear();
sequence.add("stop");
sequence.add("engineBoom");
sequence.add("start");
this.benzBuilder.setSequence(sequence);
return (BENZ)this.benzBuilder.getCarModel();
}
// 生产奔驰B型汽车
public BENZ getBENZProductB(){
this.sequence.clear();
sequence.add("horning");
sequence.add("engineBoom");
sequence.add("start");
this.benzBuilder.setSequence(sequence);
return (BENZ)this.benzBuilder.getCarModel();
}
}
(六)测试
public class Client {
public static void main(String[] args){
// 生产十辆宝马A型汽车
for(int i=0; i<10; i++){
Director mf = new Director();
BENZ bwmA = mf.getBENZProductA();
bwmA.run();
}
}
}
二、总结
(一)优点
1.易于解耦:将产品本身与产品创建过程进行解耦,可以使用相同的创建过程来得到不同的产品。也就说细节依赖抽象。2.易于精确控制对象的创建:将复杂产品的创建步骤分解在不同的方法中,使得创建过程更加清晰。
3.易于拓展:增加新的具体建造者无需修改原有类库的代码,易于拓展,符合“开闭原则“。
(二)缺点
1.建造者模式所创建的产品一般具有较多的共同点,其组成部分相似;如果产品之间的差异性很大,则不适合使用建造者模式,因此其使用范围受到一定的限制。
2.如果产品的内部变化复杂,可能会导致需要定义很多具体建造者类来实现这种变化,导致系统变得很庞大。