建造者模式
Builder模式是一步一步创建一个复杂对象的创建型模式。它允许用户在不知道内部构建细节的情况下,可以更精细地控制对象的构造流程。该模式是为了将构建复杂对象的过程和它的部件解耦,使得构建过程和部件的表示隔离开来。
一个复杂的对象有很多组成部分,如汽车,有车轮,方向盘,发动机,还有各种小零件等,如何将这些部件装配成一辆汽车,这个过程很漫长复杂,对于这种情况,为了在构建过程中对外部隐藏实现细节,可以使用Builder模式将部件和组装过程分离,使得构建过程和部件都可以自由拓展,两者之间的耦合也降到最低。
定义
将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
使用场景
- 相同的方法,不同的执行顺序,产生不同的事件结果时。
- 多个部件或者零件,都可以装配到一个对象中,但是产生的运行结果又不相同时。
- 产品类十分复杂,或者产品类中的调用顺序不同产生了不同作用,这个时候使用建造者模式十分合适。
- 当初始化一个对象特别复杂,比如参数众多,而且很多参数具有默认值时。
UML
简单实现
以M4卡宾枪为例子,默认有弹匣,枪托,枪管,机匣,扳机,撞针组成。战术版的M4卡宾枪还装配了瞄准镜,消音器,握把和激光瞄准器。
public class M4Carbine {
protected String magazine;
protected String buttstock;
protected String barrel;
protected String cartridgeReceiver;
protected String trigger;
protected String firingPin;
public M4Carbine() {
}
public void setMagazine(String magazine) {
this.magazine = magazine;
}
public void setButtstock(String buttstock) {
this.buttstock = buttstock;
}
public void setBarrel(String barrel) {
this.barrel = barrel;
}
public void setCartridgeReceiver(String cartridgeReceiver) {
this.cartridgeReceiver = cartridgeReceiver;
}
public void setTrigger(String trigger) {
this.trigger = trigger;
}
public void setFiringPin(String firingPin) {
this.firingPin = firingPin;
}
}
public class M4CarbineTacticalVersion extends M4Carbine {
protected String sightingTelescope;
protected String handle;
protected String silencer;
protected String laserSight;
public void setSightingTelescope() {
this.sightingTelescope = "全息瞄准镜";
}
public void setHandle() {
this.handle = "垂直握把";
}
public void setSilencer() {
this.silencer = "步枪消音器";
}
public void setLaserSight() {
this.laserSight = "红外瞄准器";
}
@Override
public String toString() {
return "组装了M4卡宾枪\n "+magazine+buttstock+barrel+cartridgeReceiver
+trigger+firingPin+sightingTelescope+handle+silencer+laserSight;
}
}
public class M4Builder implements Builder {
private M4CarbineTacticalVersion m4 = new M4CarbineTacticalVersion();
@Override
public void buildMagazine(String magazine) {
m4.setMagazine(magazine);
}
@Override
public void buildButtstock(String buttstock) {
m4.setButtstock(buttstock);
}
@Override
public void buildBarrel(String barrel) {
m4.setBarrel(barrel);
}
@Override
public void buildCartridgeReceiver(String cartridgeReceiver) {
m4.setCartridgeReceiver("AR15机匣");
}
@Override
public void buildTrigger(String trigger) {
m4.setTrigger(trigger);
}
@Override
public void buildFiringPin(String firingPin) {
m4.setFiringPin(firingPin);
}
@Override
public void buildSightingTelescope() {
m4.setSightingTelescope();
}
@Override
public void buildHandle() {
m4.setHandle();
}
@Override
public void buildSilencer() {
m4.setSilencer();
}
@Override
public void buildLaserSight() {
m4.setLaserSight();
}
public M4CarbineTacticalVersion create(){
return m4;
}
}
public class Director {
Builder mBuilder = null;
public Director(Builder mBuilder) {
this.mBuilder = mBuilder;
}
public void construct(String magazine,String buttstock,String barrel
,String cartridgeReceiver,String trigger,String firingPin){
mBuilder.buildMagazine(magazine);
mBuilder.buildButtstock(buttstock);
mBuilder.buildBarrel(barrel);
mBuilder.buildCartridgeReceiver(cartridgeReceiver);
mBuilder.buildTrigger(trigger);
mBuilder.buildFiringPin(firingPin);
mBuilder.buildSightingTelescope();
mBuilder.buildHandle();
mBuilder.buildSilencer();
mBuilder.buildLaserSight();
}
}
public class Test {
public static void main(String[] args) {
//构建器
Builder builder = new M4Builder();
Director director = new Director(builder);
//组装过程
director.construct("30发弹匣","AR15枪托","5.56口径枪管","AR15机匣"
,"AR15扳机","AR15撞针");
System.out.println("M4组装完成"+builder.create().toString());
}
}
运行结果:
M4组装完成组装了M4卡宾枪
30发弹匣AR15枪托5.56口径枪管AR15机匣AR15扳机AR15撞针全息瞄准镜垂直握把步枪消音器红外瞄准器
Process finished with exit code 0
建造者模式的链式调用
以上代码的实现模式我只有在学习的时候见过,通常实践中都会使用Builder模式的变种,链式调用创建对象。比如大名鼎鼎的Square公司就特喜欢用。Picasso,Retrofit的实例创建都用到了链式调用。还是以m4卡宾枪这个例子举例,将以上代码改为链式。
M4实体类还是不变
public class M4Carbine {
protected String magazine;
protected String buttstock;
protected String barrel;
protected String cartridgeReceiver;
protected String trigger;
protected String firingPin;
public M4Carbine() {
}
public void setMagazine(String magazine) {
this.magazine = magazine;
}
public void setButtstock(String buttstock) {
this.buttstock = buttstock;
}
public void setBarrel(String barrel) {
this.barrel = barrel;
}
public void setCartridgeReceiver(String cartridgeReceiver) {
this.cartridgeReceiver = cartridgeReceiver;
}
public void setTrigger(String trigger) {
this.trigger = trigger;
}
public void setFiringPin(String firingPin) {
this.firingPin = firingPin;
}
}
M4CarbineTacticalVersion修改,将Buidler类变成其静态内部类。
public class M4CarbineTacticalVersion2 extends M4Carbine {
private String sightingTelescope;
private String handle;
private String silencer;
private String laserSight;
private M4CarbineTacticalVersion2(Builder builder) {
this.sightingTelescope = builder.sightingTelescope;
this.handle = builder.handle;
this.silencer = builder.silencer;
this.laserSight = builder.laserSight;
this.magazine = builder.magazine;
this.barrel = builder.barrel;
this.buttstock = builder.buttstock;
this.cartridgeReceiver = builder.cartridgeReceiver;
this.firingPin = builder.firingPin;
this.trigger = builder.trigger;
}
@Override
public String toString() {
return "组装了M4卡宾枪\n " + magazine + buttstock + barrel + cartridgeReceiver
+ trigger + firingPin + sightingTelescope + handle + silencer + laserSight;
}
/**
* 创建静态内部类Builder
*/
public static class Builder {
private String sightingTelescope;
private String handle;
private String silencer;
private String laserSight;
private String magazine;
private String buttstock;
private String barrel;
private String cartridgeReceiver;
private String trigger;
private String firingPin;
public Builder setMagazine(String magazine) {
this.magazine = magazine;
return this;
}
public Builder setButtstock(String buttstock) {
this.buttstock = buttstock;
return this;
}
public Builder setBarrel(String barrel) {
this.barrel = barrel;
return this;
}
public Builder setCartridgeReceiver(String cartridgeReceiver) {
this.cartridgeReceiver = cartridgeReceiver;
return this;
}
public Builder setTrigger(String trigger) {
this.trigger = trigger;
return this;
}
public Builder setFiringPin(String firingPin) {
this.firingPin = firingPin;
return this;
}
//创建一个空参构造方法
public Builder() {
}
/**
* set方法返回Builder对象自身,这是链式调用的实现方式
*
* @param sightingTelescope
* @return
*/
public Builder setSightingTelescope(String sightingTelescope) {
this.sightingTelescope = sightingTelescope;
return this;
}
public Builder setHandle(String handle) {
this.handle = handle;
return this;
}
public Builder setSilencer(String silencer) {
this.silencer = silencer;
return this;
}
public Builder setLaserSight(String laserSight) {
this.laserSight = laserSight;
return this;
}
public M4CarbineTacticalVersion2 build() {
return new M4CarbineTacticalVersion2(this);
}
}
}
客户端链式调用
public class Test {
public static void main(String[] args) {
M4CarbineTacticalVersion2 m4carbine = new M4CarbineTacticalVersion2.Builder()
.setBarrel("5.56口径枪管").setFiringPin("AR15击针")
.setTrigger("AR15扳机").setMagazine("30发弹匣")
.setCartridgeReceiver("AR15机匣").setButtstock("AR15枪托")
.setHandle("三角握把").setLaserSight("红外瞄准器")
.setSightingTelescope("反射瞄准镜").setSilencer("消音器").build();
System.out.println(m4carbine.toString());
}
}
运行结果
组装了M4卡宾枪
30发弹匣AR15枪托5.56口径枪管AR15机匣AR15扳机AR15击针反射瞄准镜三角握把消音器红外瞄准器
Process finished with exit code 0