文章目錄
- 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 {@Overridepublic void buildFrame() {mBike.setFrame("鋁合金車架");}@Overridepublic void buildSeat() {mBike.setSeat("真皮車座");}@Overridepublic Bike createBike() {return mBike;}
}
//ofo單車Builder類
public class OfoBuilder extends Builder {@Overridepublic void buildFrame() {mBike.setFrame("碳纖維車架");}@Overridepublic void buildSeat() {mBike.setSeat("橡膠車座");}@Overridepublic 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);}}@Overridepublic 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);}
}