建造者模式
建造者模式(Builder Pattern)使用多个简单的对象一步一步构建成一个复杂的对象。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。
一个 Builder 类会一步一步构造最终的对象。该 Builder 类是独立于其他对象的。
刚入门的时候,其实对建造者没什么理解,基本没用过。后来见过的猪多了,逐渐懂了建造者的好处。它可以将一个复杂的对象的创建过程分成n步,控制其中的风险,与链式编程相结合后,让代码更简洁。话不多说,进入正题。
我们来造个飞机,首先要创建一个飞机类,飞机有飞机壳,发送机,价格三个属性
public class AirPlane {
//飞机壳
private String planeBody;
//发动机
private String planePower;
//价钱
private String planePrice;
public String getPlaneBody() {
return planeBody;
}
public void setPlaneBody(String planeBody) {
this.planeBody = planeBody;
}
public String getPlanePower() {
return planePower;
}
public void setPlanePower(String planePower) {
this.planePower = planePower;
}
public String getPlanePrice() {
return planePrice;
}
public void setPlanePrice(String planePrice) {
this.planePrice = planePrice;
}
}
第二步创建一个build接口,三个建造飞机属性的方法,一个创建飞机的方法
public interface PlaneBuilder {
void buildBody();
void buildPower();
void buildPrice();
AirPlane createPlane();
}
第三步,创建一个类继承build接口,也就是真正的实现类
public class BoYinPlane implements PlaneBuilder {
AirPlane airPlane = new AirPlane();
@Override
public void buildBody() {
airPlane.setPlaneBody("波音的垃圾机壳");
}
@Override
public void buildPower() {
airPlane.setPlanePower("波音的垃圾发动机");
}
@Override
public void buildPrice() {
airPlane.setPlanePrice("波音你买不起");
}
@Override
public AirPlane createPlane() {
Log.e("1111","BoYinPlane+1");
return airPlane;
}
}
public class KongkePlane implements PlaneBuilder {
AirPlane airPlane = new AirPlane();
@Override
public void buildBody() {
airPlane.setPlaneBody("空客的飞机外壳");
}
@Override
public void buildPower() {
airPlane.setPlanePower("空客的发动机");
}
@Override
public void buildPrice() {
airPlane.setPlanePrice("空客卖10000万");
}
@Override
public AirPlane createPlane() {
Log.e("1111","KongkePlane+1");
return airPlane;
}
}
第四步,创建操作者Director
public class Director {
private PlaneBuilder mBuilder = null;
public Director(PlaneBuilder builder) {
mBuilder = builder;
}
public AirPlane construct() {
mBuilder.buildBody();
mBuilder.buildPower();
mBuilder.buildPrice();
return mBuilder.createPlane();
}
}
第五步,调用
Director director = new Director(new BoYinPlane());
AirPlane construct = director.construct();
System.out.println("价格"+construct.getPlanePrice());
Director director1 = new Director(new KongkePlane());
AirPlane construct1 = director1.construct();
System.out.println("价格"+construct1.getPlanePrice());
打印结果
2019-04-19 14:22:38.725 5782-5782/com.yihui.designmodedemo E/1111: BoYinPlane+1
2019-04-19 14:22:38.727 5782-5782/com.yihui.designmodedemo I/System.out: 价格波音你买不起
2019-04-19 14:22:38.728 5782-5782/com.yihui.designmodedemo E/1111: KongkePlane+1
2019-04-19 14:22:38.728 5782-5782/com.yihui.designmodedemo I/System.out: 价格空客卖10000万
其实建造者还有另外一种写法,就是大家常见到的链式写法
public class NewAirPlane {
//飞机壳
private String planeBody;
//发动机
private String planePower;
//价钱
private String planePrice;
public NewAirPlane() {
throw new RuntimeException("can’t init");
}
private NewAirPlane(Builder builder){
planeBody = builder.planeBody;
planePower = builder.planePower;
planePrice = builder.planePrice;
}
public static final class Builder {
private String planeBody;
private String planePower;
private String planePrice;
public Builder() {}
public Builder buildBody(String val) {
planeBody = val;
return this;
}
public Builder buildPower(String val) {
planePower = val;
return this;
}
public Builder buildPrice(String val) {
planePrice = val;
return this;
}
public NewAirPlane createAire() {
Log.e("1111","飞机制造成功");
return new NewAirPlane(this);
}
}
public void showPlane(){
Log.e("*************","飞机机身:"+planeBody+";飞机发动机:"+planePower+";价格:"+planePrice);
}
}
调用,然后打印结果
NewAirPlane newAirPlane = new NewAirPlane
.Builder()
.buildBody(new BoYinPlane().createPlane().getPlaneBody())
.buildPower("国产发动机")
.buildPrice("白送")
.createAire()
;
newAirPlane.showPlane();
2019-04-19 14:29:00.489 5988-5988/com.yihui.designmodedemo E/1111: BoYinPlane+1
2019-04-19 14:29:00.489 5988-5988/com.yihui.designmodedemo E/1111: 飞机制造成功
2019-04-19 14:29:00.491 5988-5988/com.yihui.designmodedemo E/*************: 飞机机身:null;飞机发动机:国产发动机;价格:白送
优点: 1、建造者独立,易扩展。 2、便于控制细节风险。
缺点: 1、产品必须有共同点,范围有限制。 2、如内部变化复杂,会有很多的建造类。
使用场景: 1、需要生成的对象具有复杂的内部结构。 2、需要生成的对象内部属性本身相互依赖。
注意事项:与工厂模式的区别是:建造者模式更加关注与零件装配的顺序。