什么是建造者模式?
建造者模式也可以成为创建者模式,目的是为了将复杂对象的构建与它的表示分离,使同样的构建过程可以创建不同的表示。创建者模式隐藏了复杂对象的创建过程。
建造者模式的适用场景
- 类的创建过程复杂,用户不需要知道对象构建细节
- 对象构建过程和细节需要封装和复用
建造者模式的优点
- 复杂对象的创建和使用分离,相同的方法,不同执行顺序,产生不同的事件结果。
- 多个部件都可以装配到一个对象中,但产生的运行结果不相同
- 用户不知道对象的建造过程和细节的情况下就可以直接创建复杂对象
建造者模式的缺点
建造者模式中的角色和类图
建造者模式中的角色
- builder(建造者)
- Builder角色负责定义用于生成实例的接口(API),Builder角色中准备了用于生成实例的方法。
- ConcreteBuilder(具体的建造者)
- ConcreteBuilder角色是负责实现Builder角色的接口的类(API)。
- Director(监工)
- Director角色负责使用Builder角色的接口来生成实例。
建造者模式类图
链式调用建造者模式中的角色
- builder(建造者)
- 链式调用builder的构造器是私有的,通过
builder
静态方法创建builder对象,每个set函数返回的是本builer对象,set完成之后通过build
函数创建目标对象。
- 链式调用builder的构造器是私有的,通过
链式调用建造者模式类图
代码实现
基础版代码实现
我们来模拟一个手机类,用建造者模式实现手机创建的过程
第一步:首先写手机物料的接口
电池接口
public interface Battery {
/**
* 获取电池容量
*
* @return
*/
long getCapacity();
/**
* 获取电池充电时间
*
* @return
*/
long getChargeTime();
}
屏幕接口
public interface Screen {
/**
* 屏幕颜色
*
* @return
*/
long getSize();
/**
* 屏幕亮度
*
* @return
*/
long getLight();
}
第二步:实现手机物料接口,创建手机物料实现类
小电池
@ToString
public class LittleBattery implements Battery{
private long capacity;
private long chargeTime;
public LittleBattery() {
this.capacity = 1400L;
this.chargeTime = 30L;
}
@Override
public long getCapacity() {
return capacity;
}
@Override
public long getChargeTime() {
return chargeTime;
}
}
大电池
@ToString
public class LargeBattery implements Battery{
private long capacity;
private long chargeTime;
public LargeBattery() {
this.capacity = 4000L;
this.chargeTime = 60L;
}
@Override
public long getCapacity() {
return capacity;
}
@Override
public long getChargeTime() {
return chargeTime;
}
}
好的屏幕
public class GoodScreen implements Screen{
@Override
public long getSize() {
return 64L;
}
@Override
public long getLight() {
return 300L;
}
}
第三步:创建手机类
@Data
public class Mobile {
private String brand;
private String type;
private Screen screen;
private String color;
private Battery battery;
private String weight;
private String size;
}
第四步:创建手机Builder
抽象类,这个对象对应builder
角色
public abstract class AbstractMobileBuilder {
public abstract void setBrand();
public abstract void setType(String type);
public abstract void setScreen(Screen screen);
public abstract void setColor(String color);
public abstract void setBattery(Battery battery);
public abstract void setWeight(String weight);
public abstract void setSize(String size);
public abstract Mobile buildMobile();
}
第五步:创建具体手机Builder实现类,这个对象对应ConcreteBuilder
角色
创建OPPO
手机Builder
类
public class OPPOMobileMobileBuilder extends AbstractMobileBuilder {
private Mobile mobile = new Mobile();
private final String brand = "OPPO";
@Override
public void setBrand() {
mobile.setBrand(brand);
}
@Override
public void setType(String type) {
mobile.setType(type);
}
@Override
public void setScreen(Screen screen) {
mobile.setScreen(screen);
}
@Override
public void setColor(String color) {
mobile.setColor(color);
}
@Override
public void setBattery(Battery battery) {
mobile.setBattery(battery);
}
@Override
public void setWeight(String weight) {
mobile.setWeight(weight);
}
@Override
public void setSize(String size) {
mobile.setSize(size);
}
@Override
public Mobile buildMobile() {
return mobile;
}
}
创建Huawei
手机builder
类
public class HuaweiMobileMobileBuilder extends AbstractMobileBuilder {
private Mobile mobile = new Mobile();
private final String brand = "Huawei";
@Override
public void setBrand() {
mobile.setBrand(brand);
}
@Override
public void setType(String type) {
mobile.setType(type);
}
@Override
public void setScreen(Screen screen) {
mobile.setScreen(screen);
}
@Override
public void setColor(String color) {
mobile.setColor(color);
}
@Override
public void setBattery(Battery battery) {
mobile.setBattery(battery);
}
@Override
public void setWeight(String weight) {
mobile.setWeight(weight);
}
@Override
public void setSize(String size) {
mobile.setSize(size);
}
@Override
public Mobile buildMobile() {
return mobile;
}
}
第六步:创建Client
类测试
public class Client {
public static void main(String[] args) {
Director appleDirector = new Director(new OPPOMobileMobileBuilder());
Mobile oppoMobile = appleDirector.constructor(new LargeBattery(), "Reno", "red", new GoodScreen(), "6.4", "230");
System.out.println("OPPO手机:"+oppoMobile);
System.out.println("\n"+"==========我是分割线========="+"\n");
Director huaweiDirector = new Director(new HuaweiMobileMobileBuilder());
Mobile huaweiMobile = huaweiDirector.constructor(new LittleBattery(), "P40", "blue", new GoodScreen(), "6.4", "200");
System.out.println("Huawei手机:"+huaweiMobile);
}
}
执行结果
链式调用版本写法
之前的写法constructor函数中传入过多的参数,代码比较复杂,容易出错。还有一种比较常用的链式调用写法。前三步和基础版本相同,因此我们直接从第四步开始写代码。
第四步:创建builder实现类,这个类对应ConcreteBuilder
角色。
Huawei手机builder实现类
public class HuaweiMobileMobileBuilder2 {
private Mobile mobile;
private String brand;
private String type;
private Screen screen;
private String color;
private Battery battery;
private String weight;
private String size;
// 构造函数私有化
private HuaweiMobileMobileBuilder2() {
this.mobile = new Mobile();
}
// 创建新的builder
public static HuaweiMobileMobileBuilder2 builder() {
return new HuaweiMobileMobileBuilder2();
}
public HuaweiMobileMobileBuilder2 setBrand() {
this.brand = "Huawei";
return this;
}
public HuaweiMobileMobileBuilder2 setType(String type) {
this.type = type;
return this;
}
public HuaweiMobileMobileBuilder2 setScreen(Screen screen) {
this.screen = screen;
return this;
}
public HuaweiMobileMobileBuilder2 setColor(String color) {
this.color = color;
return this;
}
public HuaweiMobileMobileBuilder2 setBattery(Battery battery) {
this.battery = battery;
return this;
}
public HuaweiMobileMobileBuilder2 setWeight(String weight) {
this.weight = weight;
return this;
}
public HuaweiMobileMobileBuilder2 setSize(String size) {
this.size = size;
return this;
}
// 返回创建好的mobile
public Mobile build() {
this.mobile.setBrand(this.brand);
this.mobile.setType(this.type);
this.mobile.setSize(this.size);
this.mobile.setWeight(this.weight);
this.mobile.setBattery(battery);
this.mobile.setColor(this.color);
this.mobile.setScreen(this.screen);
return mobile;
}
}
OPPO手机builder实现类
public class OPPOMobileMobileBuilder2 {
private Mobile mobile;
private String brand;
private String type;
private Screen screen;
private String color;
private Battery battery;
private String weight;
private String size;
// 构造函数私有化
private OPPOMobileMobileBuilder2() {
}
// 获取新的builder
public static OPPOMobileMobileBuilder2 builder() {
return new OPPOMobileMobileBuilder2();
}
public OPPOMobileMobileBuilder2 setBrand() {
this.brand = "OPPO";
return this;
}
public OPPOMobileMobileBuilder2 setType(String type) {
this.type = type;
return this;
}
public OPPOMobileMobileBuilder2 setScreen(Screen screen) {
this.screen = screen;
return this;
}
public OPPOMobileMobileBuilder2 setColor(String color) {
this.color = color;
return this;
}
public OPPOMobileMobileBuilder2 setBattery(Battery battery) {
this.battery = battery;
return this;
}
public OPPOMobileMobileBuilder2 setWeight(String weight) {
this.weight = weight;
return this;
}
public OPPOMobileMobileBuilder2 setSize(String size) {
this.size = size;
return this;
}
public Mobile build() {
this.mobile = new Mobile();
this.mobile.setBrand(this.brand);
this.mobile.setType(this.type);
this.mobile.setSize(this.size);
this.mobile.setWeight(this.weight);
this.mobile.setBattery(battery);
this.mobile.setColor(this.color);
this.mobile.setScreen(this.screen);
return mobile;
}
}
第五步:Client类调用测试
public class Client2 {
public static void main(String[] args) {
Mobile huaweiMobile = HuaweiMobileMobileBuilder2.builder()
.setBattery(new LittleBattery())
.setType("P40")
.setColor("blue")
.setScreen(new GoodScreen())
.setSize("6.4")
.setWeight("200")
.build();
System.out.println("华为手机:"+huaweiMobile);
System.out.println("\n"+"==========我是分割线========="+"\n");
Mobile oppoMobile = OPPOMobileMobileBuilder2.builder()
.setBattery(new LargeBattery())
.setType("Reno")
.setColor("red")
.setScreen(new GoodScreen())
.setSize("6.4")
.setWeight("230")
.build();
System.out.println("OPPO手机:"+oppoMobile);
}
}