文章目录
- 1、建造者模式
- 2、案例:共享单车的创建
- 3、其他用途
1、建造者模式
- 某个对象的构建复杂
- 将复杂的对象的创建 和 属性赋值所分离,使得同样的构建过程可以创建不同的表示
- 建造的过程和细节调用者不需要知道,只需要通过构建者去进行操作
如,主机这个负责对象的构建,分离承诺内存条、主板这些部件,再组装构建。内存条替换一个别的,出来就是一个不同的对象。
建造者模式相关角色:
- 产品类:复杂对象,主机
- 抽象建造者类Builder:规定要实现复杂对象的哪些部件的创建
- 具体建造者类ConcreteBuilder:实现Builder,完成各个部件的具体创建
- 指挥者类Director:保证对象的各个部分按照某种顺序创建
2、案例:共享单车的创建
摩拜单车和ofo单车。Bike是产品,包含车架,车座等组件;Builder是抽象建造者,MobikeBuilder和OfoBuilder是具体的建造者,Director是指挥者。
具体的代码如下:
//自行车类
@Data
public class Bike {
private String frame; //车架
private String seat; //座椅
}
抽象构建者Builder定义哪些部分要构建:
// 抽象 builder 类
public abstract class Builder {
protected Bike mBike = new Bike();
public abstract void buildFrame(); //构建车架
public abstract void buildSeat(); //构建座椅
public abstract Bike createBike(); //构建自行车
}
写具体的构建者:
//摩拜单车Builder类
public class MobikeBuilder extends Builder {
@Override
public void buildFrame() {
mBike.setFrame("铝合金车架");
}
@Override
public void buildSeat() {
mBike.setSeat("真皮车座");
}
@Override
public Bike createBike() {
return mBike;
}
}
//ofo单车Builder类
public class OfoBuilder extends Builder {
@Override
public void buildFrame() {
mBike.setFrame("碳纤维车架");
}
@Override
public void buildSeat() {
mBike.setSeat("橡胶车座");
}
@Override
public Bike createBike() {
return mBike;
}
}
指挥者类:
//指挥者类
public class Director {
private Builder mBuilder; //声明Builder类型的变量
public Director(Builder builder) {
mBuilder = builder;
}
//组装自行车的方法
public Bike construct() {
mBuilder.buildFrame();
mBuilder.buildSeat();
return mBuilder.createBike();
}
}
客户端测试:
public class Client {
public static void main(String[] args) {
showBike(new OfoBuilder());
showBike(new MobikeBuilder());
}
private static void showBike(Builder builder) {
Director director = new Director(builder); //创建指挥者
Bike bike = director.construct(); //让指挥者指挥组装
System.out.println(bike.getFrame());
System.out.println(bike.getSeat());
}
}
再有新的单车公司加入,只需实现一个新的建造者类即可,符合开闭原则。但如果创建的产品组成部分差异很大,则不适合用建造者模式,比如要再造个电脑对象。
3、其他用途
@Setter
@Getter
public class Phone {
private String cpu;
private String screen;
private String memory;
private String mainboard;
public Phone(String cpu, String screen, String memory, String mainboard) {
this.cpu = cpu;
this.screen = screen;
this.memory = memory;
this.mainboard = mainboard;
}
}
对于属性多的对象,创建其对象往往可读性很差,如:
//构建Phone对象
Phone phone = new Phone("intel","三星屏幕","金士顿","华硕");
重构一下(@Builder注解的思路):
public class Phone {
private String cpu;
private String screen;
private String memory;
private String mainboard;
//私有的构造方法
private Phone(Builder builder) {
cpu = builder.cpu;
screen = builder.screen;
memory = builder.memory;
mainboard = builder.mainboard;
}
public static final class Builder {
private String cpu;
private String screen;
private String memory;
private String mainboard;
public Builder() {}
public Builder cpu(String val) {
cpu = val;
return this;
}
public Builder screen(String val) {
screen = val;
return this;
}
public Builder memory(String val) {
memory = val;
return this;
}
public Builder mainboard(String val) {
mainboard = val;
return this;
}
//!!!!!
public Phone build() {
return new Phone(this);
}
}
@Override
public String toString() {
return "Phone{" +
"cpu='" + cpu + '\'' +
", screen='" + screen + '\'' +
", memory='" + memory + '\'' +
", mainboard='" + mainboard + '\'' +
'}';
}
}
此时就可链式编程创建这个对象(new Phone.Builder()
创建静态内部类对象):
public class Client {
public static void main(String[] args) {
Phone phone = new Phone.Builder()
.cpu("intel")
.mainboard("华硕主板")
.memory("金士顿内存")
.screen("三星屏幕")
.build();
System.out.println(phone);
}
}