简介
建造者模式也叫“构造者模式”,实际开发过程中称之为 Builder 模式
定义
将一个复杂对象的构建与其表示分离,使得同样的构建过程可以创建不同的表示
场景
当一个类的构造函数参数个数超过4个,而且这些参数有些是可选的参数,考虑使用构造者模式
例如我们现在有如下一个类汽车类Car,其中tyre、motor是必填参数,而其他3个是可选参数,那么我们如何构造这个类的实例呢
通常有两种常用的方式:
public class Car {
// 轮胎 必填
private String tyre;
// 发动机 必填
private String motor;
// 导航 可选
private String navigation;
// 防抱死系统 可选
private boolean abs;
// esc 车身稳定系统 可选
private boolean esc;
}
第一:折叠构造函数模式(telescoping constructor pattern ),这个我们经常用,如下代码所示
public class Car {
...
public Car(String tyre, String motor) {
this(tyre, motor, "gps");
}
public Car(String tyre, String motor, String gps) {
this(tyre, motor, gps,false);
}
public Car(String tyre, String motor, String gps, boolean abs) {
this(tyre, motor, gps, abs, false);
}
public Car(String tyre, String motor, String navigation, boolean abs, boolean esc) {
this.tyre = tyre;
this.motor = motor;
this.navigation = navigation;
this.abs = abs;
this.esc = esc;
}
}
第二种 JavaBean 模式
public class Car {
...
public String getTyre() {
return tyre;
}
public void setTyre(String tyre) {
this.tyre = tyre;
}
public String getMotor() {
return motor;
}
public void setMotor(String motor) {
this.motor = motor;
}
public String getNavigation() {
return navigation;
}
public void setNavigation(String navigation) {
this.navigation = navigation;
}
...
}
那么这两种方式有什么弊端呢?
第一种主要是使用及阅读不方便。你可以想象一下,当你要调用一个类的构造函数时,你首先要决定使用哪一个,然后里面又是一堆参数,如果这些参数的类型很多又都一样,你还要搞清楚这些参数的含义,很容易就传混了...
第二种方式在构建过程中对象的状态容易发生变化,造成错误。因为那个类中的属性是分步设置的,所以就容易出错。
为了解决这两个痛点,builder模式就横空出世了。
如何实现
在Car 中创建一个静态内部类 Builder,然后将Car 中的参数都复制到Builder类中。
在Car中创建一个private的构造函数,参数为Builder类型
在Builder中创建一个public的构造函数,参数为Car中必填的那些参数,tyre 和 motor。
在Builder中创建设置函数,对Car中那些可选参数进行赋值,返回值为Builder类型的实例
在Builder中创建一个build()方法,在其中构建Car的实例并返回
@Data
public class Car {
// 轮胎 必填
private String tyre;
// 发动机 必填
private String motor;
// 导航 可选
private String navigation;
// 防抱死系统 可选
private boolean abs;
// esc 车身稳定系统 可选
private boolean esc;
//省略getter
...
private Car(Builder builder){
this.tyre=builder.tyre;
this.motor=builder.motor;
this.navigation=builder.navigation;
this.abs=builder.abs;
this.esc=builder.esc;
}
public static class Builder{
// 轮胎 必填
private String tyre;
// 发动机 必填
private String motor;
// 导航 可选
private String navigation;
// 防抱死系统 可选
private boolean abs;
// esc 车身稳定系统 可选
private boolean esc;
public Builder(String tyre,String motor){
this.tyre = tyre;
this.motor = motor;
}
public Builder setNavigation(String navigation) {
this.navigation = navigation;
return this;
}
public Builder setAbs(boolean abs) {
this.abs = abs;
return this;
}
public Builder setEsc(boolean esc) {
this.esc = esc;
return this;
}
public Car build(){
return new Car(this);
}
}
}
在客户端使用链式调用,一步一步的把对象构建出来
Car car = new Car.Builder("米其林","1.5T发动机")
.setNavigation("北斗")
.setAbs(true)
.setEsc(false)
.build();
总结
构建者模式是一个非常实用而常见的创建类型的模式(creational design pattern),例如图片处理框架Glide,网络请求框架Retrofit等都使用了此模式。
网友评论