能看到這篇文章的讀者,我想應該或多或少了解Builder建構者模式。在Builder模式出現之前,建構對象會有如下兩個問題:
- 在屬性過多的情況下,需要在構造函數中一次性傳遞所有需要初始化的參數,并且可能會根據需求override多個不同參數組合的構造函數。比較麻煩。
- 如果是建立一個無參的空對象,通過setter方法,為每一個屬性值指派的話,有一個很大的問題就是會出現對象不一緻的情況。也就是說由于setter方法可以在任何時間和地方可以為對象屬性重新指派,可能導緻程式上下文對象的屬性出現不一緻的情況,這在序列化或者多線程的情境下會因為對象不一緻而産生bug隐患。
Builder建構者模式就可以很好的解決上述的兩個問題。好了廢話不多說,直接上CODE。下面我通過一個Config類,來實作一個建構者模式,其他情況可以參考這個進行相應修改。思路是一緻的。
public class Config {
private String protocol;
private String ip;
private String port;
public String getProtocol() {
return protocol;
}
public String getIp() {
return ip;
}
public String getPort() {
return port;
}
@Override
public String toString() {
return "Config{" +
"protocol='" + protocol + '\'' +
", ip='" + ip + '\'' +
", port='" + port + '\'' +
'}';
}
//新增Builder靜态類并賦預設值
public static class Builder {
private String protocol = "http://";
private String ip = "127.0.0.1";
private String port = "80";
//為每一個屬性建立傳回自身Builder對象的方法
public Builder setProtocol(String protocol) {
this.protocol = protocol;
return this;
}
public Builder setIp(String ip) {
this.ip = ip;
return this;
}
public Builder setPort(String port) {
this.port = port;
return this;
}
//建立一個aplly方法,傳一個父類引用,指派建構的參數
public void apply2Super(Config config) {
config.protocol = this.protocol;
config.ip = this.ip;
config.port = this.port;
}
//建立一個build方法,建立一個父類對象,傳遞給apply方法為這個空對象賦建構出來的參數值,傳回這個建構對象即可。
public Config build(){
Config config = new Config();
apply2Super(config);
return config;
}
}
}
調用方式:
//使用預設值建構
Config config1 = new Config.Builder().build();
System.out.println(config1);
//自定義構造參數
Config config = new Config.Builder()
.setProtocol("https://")
.setIp("192.168.0.1.")
.setPort("8080")
.build();
System.out.println(config);
總結
1、在需要構造的類中新增Builder靜态類并賦預設值
2、為每一個屬性建立傳回自身Builder對象的方法
3、建立一個aplly方法,傳一個父類引用,指派建構的參數
4、建立一個build方法,建立一個父類對象,傳遞給apply方法為這個空對象賦建構出來的參數值,傳回這個建構對象即可。
P.S:
給大家安利一本書《大話設計模式》 作者是程傑的那個。這本書通俗易懂的講解了所有的設計模式,是我看到過的所有講設計模式中,最容易了解,最幹淨利索的。我現在正在根據書中講的和我自身的了解,實作每一個設計模式。github位址:https://github.com/longzhiwuing/GOFDemos 歡迎拍磚和STAR