建造者模式:是指“将一个复杂对象的构建与他的表示进行分离”。使得同样的构建过程可以创建不同的表示。
是不是有点不理解,初次看我也不是很理解。那么接下来我们先看应用优势,与时机。
优势:
- 客户端无需了解产品内部情况。
- 通过新的具体建造者,即可改变产品的内部结构
- 四个角色构成相互独立,具备高扩展性
- 通过对建造过程的细化,可降低项目维护的风险
使用:
- 产品对象有一个较复杂的内部结构,并且其具体的构建方法面临着复杂的变化。
- 产品类的构建过程中,可使被构造对象有不同表现时
- 创建对象时,需要调用软件系统的其他对象。
具体的构成:
- Builder(抽象建造者角色)
- 为创建一个Product对象的各个部件制定抽象接口
- ConcreteBuilder(具体建造者角色)
- 实现Builder的接口以构造和装配该产品的各个部件。
- 定义并说明它所创建的表示
- 提供一个检索产品的接口
- Director(导演者角色)
- 构造一个使用Builder接口的对象
- Product(产品角色)
- 表示被构造的复杂对象。ConcreteBuilder 创建该产品的内部表示并定义他的装配过程。
- 包含定义组成组件的类。包括将这些组件装配成最终产品的接口
来个例子:
1.产品:我并不想放具体建造者角色,我想放的是产品角色(因为,我们总得知道最终的产品是什么样子的才能生产。)
/**
* 产品 西门子冰箱(产品)
*/
public class SiemensWasher {
private String washerSkeleton;
private Compressor washerEngine;
private String wahserWheels;
private String wahserDoor;
private String wahserColor;
public SiemensWasher() {
}
public void setWasherSkeleton(String washerSkeleton) {
this.washerSkeleton = washerSkeleton;
}
public void setWasherEngine(Compressor washerEngine) {
this.washerEngine = washerEngine;
}
public void setWahserWheels(String wahserWheels) {
this.wahserWheels = wahserWheels;
}
public void setWahserColor(String wahserColor) {
this.wahserColor = wahserColor;
}
public void setWahserDoor(String wahserDoor) {
this.wahserDoor = wahserDoor;
}
@Override
public String toString() {
return "SiemensWasher{" +
"washerSkeleton='" + washerSkeleton + '\'' +
", washerEngine=" + washerEngine +
", wahserWheels='" + wahserWheels + '\'' +
", wahserColor='" + wahserColor + '\'' +
'}';
}
}
因为里边有个自定义的类:
**
* 一个部件对象,压缩机
*/
public class Compressor {
private String name;
public Compressor(String name) {
this.name = name;
}
@Override
public String toString() {
return "Compressor{" +
"name='" + name + '\'' +
'}';
}
}
2..抽象建造者:
//建造冰箱的框架
public interface WasherBuilder {
/**
* 建造冰箱的框架,抽象建造者
*/
void buildeWasherSkeleton();
/**
* 建造冰箱的压缩机
*/
void buildeWasherEngine();
/**
* 给冰箱装上轮子
*/
void buildeWasherWheels();
/**
* 安装冰箱身体(包含冰箱们,涂颜色)
*/
void buildeWasherBody();
}
3.既然有的抽象的建造者角色,那么总得有实现他的具体建造者角色吧。
public class SiemensWasherBuilder implements WasherBuilder {
private SiemensWasher siemensWasher = new SiemensWasher();
@Override
public void buildeWasherSkeleton() {
siemensWasher.setWahserDoor("冰箱门");
siemensWasher.setWahserColor("银色");
}
@Override
public void buildeWasherEngine() {
Compressor compressor = new Compressor("新型压缩机");
siemensWasher.setWasherEngine(compressor);
}
@Override
public void buildeWasherWheels() {
siemensWasher.setWahserWheels("冰箱轮");
}
@Override
public void buildeWasherBody() {
siemensWasher.setWasherSkeleton("冰箱框架");
}
public SiemensWasher retrieveWasher(){
return siemensWasher;
}
}
现在,我们的能建造我们想要的产品了。但是,这个产品由谁说了算,你现在要创建那种产品?(为什么会有个那种产品,这个解决的就是将一个复杂的对象的构建与他的表示分离。使得同样的构建过程可以创建不同的表示)。所以,我们这里需要一个导演着角色。
public class SiemensDirector {
WasherBuilder builder;
public SiemensDirector(WasherBuilder washerBuilder) {
this.builder = washerBuilder;
}
/**
* 按照一定的方法或规则建造冰箱
*/
public void contruct(){
builder.buildeWasherSkeleton();
builder.buildeWasherEngine();
builder.buildeWasherWheels();
builder.buildeWasherBody();
}
}
我们在导演者中定义了一个抽象的建造者的角色的属性,这个属性也是接口。然后定义了创造产品的步骤。那么,我们就可以产出我们想要的产品。
测试:
//1.创建一个建造者对象:
// SiemensWasherBuilder builder = new SiemensWasherBuilder();
OurWasherBuilder builder = new OurWasherBuilder();
//2.创建一个导演,并为他创建一个建造者
SiemensDirector director = new SiemensDirector(builder);
//3.通知建造者创建产品
director.contruct();
//4.从具体建造者中检索产品(返回是冰箱的轮子)
SiemensWasher siemensWasher = builder.retrieveWasher();
System.out.println(siemensWasher);
我把第一行注释了,然后用了一个没有出现的建造者的具体实现类。都一样,那么我们看。
首先,我们导演者,让我们创建一个具体的产品,这个产品按照什么样子来呢,那么就是按照不同的具体实现类的builder了。
我把我自定义的一个另外一个具体实现类展示出来
/**
* 定义我们自己的冰箱
*/
public class OurWasherBuilder implements WasherBuilder {
private SiemensWasher siemensWasher = new SiemensWasher();
@Override
public void buildeWasherSkeleton() {
siemensWasher.setWahserDoor("冰箱门");
siemensWasher.setWahserColor("白色");
}
@Override
public void buildeWasherEngine() {
Compressor compressor = new Compressor("新型压缩机");
siemensWasher.setWasherEngine(compressor);
}
@Override
public void buildeWasherWheels() {
siemensWasher.setWahserWheels("黑冰箱轮");
}
@Override
public void buildeWasherBody() {
siemensWasher.setWasherSkeleton("冰箱框架");
}
public SiemensWasher retrieveWasher(){
return siemensWasher;
}
}