天天看點

Builder建構者模式 通用模闆

能看到這篇文章的讀者,我想應該或多或少了解Builder建構者模式。在Builder模式出現之前,建構對象會有如下兩個問題:

  1. 在屬性過多的情況下,需要在構造函數中一次性傳遞所有需要初始化的參數,并且可能會根據需求override多個不同參數組合的構造函數。比較麻煩。
  2. 如果是建立一個無參的空對象,通過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

繼續閱讀