建造者(Builder)模式

前言

建造者模式即BUilder模式,看名字就可知是一種創(chuàng)建型模式瀑志。主要是解決

  1. 構(gòu)造方法中參數(shù)過多導(dǎo)致的可讀性較差的問題涩搓;
  2. 在初始化時不必將所有參數(shù)進行設(shè)置的情況(通常有默認(rèn)值)。
    文中會舉例進行演示劈猪,通過例子能夠有一個更清晰的認(rèn)識昧甘。

場景描述

許多游戲在進入游戲時,第一步往往是讓我們選擇角色的外形战得,如眼睛顏色充边,眼睛大小,發(fā)型常侦,頭發(fā)顏色浇冰,臉型等等予弧。假設(shè)現(xiàn)在要創(chuàng)建一個小明,大眼湖饱,綠色的瞳孔掖蛤,中分頭,紅色頭發(fā)井厌,鞋拔子臉蚓庭。當(dāng)然還有必填的姓名。

首先仅仆,我們創(chuàng)建一個Person的類器赞,并改寫toString方法便于測試。

public class Person {
    private String name;//姓名必填
    private String eyeSize;//眼睛大小
    private String eyeColor;//眼睛顏色
    private String hairStyle;//發(fā)型
    private String hairColor;//頭發(fā)顏色
    private String face;//臉型

    public Person(String name, String eyeSize, String eyeColor, String hairStyle, String hairColor, String face) {
        this.name = name;
        this.eyeSize = eyeSize;
        this.eyeColor = eyeColor;
        this.hairStyle = hairStyle;
        this.hairColor = hairColor;
        this.face = face;
    }

    @Override
    public String toString() {
        String s = "姓名:" + name + "\n"
                + "眼睛:" + eyeSize + "\n"
                + "眼睛顏色:" + eyeColor + "\n"
                + "發(fā)型:" + hairStyle + "\n"
                + "頭發(fā)顏色:" + hairColor + "\n"
                + "臉型:" + face;
        return s;
    }
}

同時我們編寫測試類墓拜,創(chuàng)建小明這個角色港柜。在創(chuàng)建時我郁悶了,在通過構(gòu)造方法對對象進行初始化時咳榜,我忘記了參數(shù)的順序夏醉。雖然現(xiàn)在IDE都非常的智能,會對參數(shù)進行提示涌韩,但是還是影響了我的開發(fā)效率畔柔。

最后我們艱辛的創(chuàng)建完了這個簡單的測試類

public static void main(String[] args) {

    Person xiaoming = new Person("小明","大", "綠色", "中分", "紅色", "鞋拔子臉");

    System.out.println(xiaoming.toString());

}

輸入結(jié)果如下:

姓名:小明
眼睛:大
眼睛顏色:綠色
發(fā)型:中分
頭發(fā)顏色:紅色
臉型:鞋拔子臉

老鐵,沒毛病臣樱。但是現(xiàn)在是只有6個參數(shù)的情況下靶擦,似乎還可以接受,但是如果再多幾個雇毫,orzP丁!

使用Builder模式

首先來說說使用Builder模式有什么優(yōu)點:

  1. 默認(rèn)參數(shù)棚放,無需對所有參數(shù)進行初始化枚粘;
  2. 將實現(xiàn)變成鏈?zhǔn)秸{(diào)用,增加了代碼可讀性席吴。

現(xiàn)在不管角色的外形赌结,我只想創(chuàng)建一個小明的對象,來看看Builder模式會怎么做:

public static void main(String[] args) {
    Person xiaoming = new Person.Builder("小明").create();

    System.out.println(xiaoming.toString());
}
圖片.png

Are you kidding孝冒?就傳了個必填項姓名就創(chuàng)建好了柬姚?僅用一行代碼就創(chuàng)建好了這個對象。

在前言中講到過一點庄涡,設(shè)置默認(rèn)值量承。以上實現(xiàn)就是基于默認(rèn)值的設(shè)置。

接下來就來到了緊張刺激的代碼實現(xiàn)環(huán)節(jié)。Builder的實現(xiàn)

public class Person {
    private String name;//姓名必填
    //省略其他可選參數(shù)

    private Person(Builder builder) {  //1............
        initialize(builder);
    }

    private void initialize(final Builder builder) {
        name = builder.name;
        //省略
    }


    public static class Builder {
        //2..........
        private String name;//姓名必填
        private String eyeSize = "大";//眼睛大小
        //省略

        public Builder(String name) {
            this.name = name;
        }

        public Builder setEyeSize(String eyeSize) {
            this.eyeSize = eyeSize;
            //3..........
            return this;
        }

        //省略

        //4..........
        public Person create() {
            return new Person(this);
        }
    }

    @Override
    public String toString() {
        String s = "姓名:" + name + "\n"
                + "眼睛:" + eyeSize + "\n"
                + "眼睛顏色:" + eyeColor + "\n"
                + "發(fā)型:" + hairStyle + "\n"
                + "頭發(fā)顏色:" + hairColor + "\n"
                + "臉型:" + face;
        return s;
    }
}

劃一下重點:

  1. 因為我們要用過Builder來創(chuàng)建對象撕捍,所有需將Person類的構(gòu)造方法私有化拿穴,且通過Builder來構(gòu)建;
  2. 在Builder中初始化變量,對外部提供set方法;
  3. 實現(xiàn)鏈?zhǔn)降年P(guān)鍵 return this;
  4. 設(shè)置完參數(shù)之后通過Person類的構(gòu)造進行構(gòu)建并返回實例對象忧风。

繼續(xù)創(chuàng)建一個好看點的小紅:

    Person xiaohong = new Person.Builder("小紅")
            .setEyeColor("藍(lán)色")
            .setEyeSize("大")
            .setFace("鵝蛋臉")
            .setHairStyle("大波浪")
            .setHairColor("褐色")
            .create();

是不是格外的清晰默色。

總結(jié)

將代碼寫成鏈?zhǔn)绞欠浅?yōu)美的事情,像在Android開發(fā)中狮腿,我們可以將TitleBar的設(shè)置寫成鏈?zhǔn)酵仍祝部梢詫ecyclerView的初始化過程寫成鏈?zhǔn)剑?br> 看過dagger2生成的代碼就可以看出,文中builder模式是仿造它的實現(xiàn)缘厢,要是沒看過現(xiàn)在也可以轉(zhuǎn)去看吃度,相信會輕松許多;
完整代碼移步gayhub贴硫。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末椿每,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子英遭,更是在濱河造成了極大的恐慌间护,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,546評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件贪绘,死亡現(xiàn)場離奇詭異兑牡,居然都是意外死亡央碟,警方通過查閱死者的電腦和手機税灌,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,224評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來亿虽,“玉大人菱涤,你說我怎么就攤上這事÷迕悖” “怎么了粘秆?”我有些...
    開封第一講書人閱讀 164,911評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長收毫。 經(jīng)常有香客問我攻走,道長,這世上最難降的妖魔是什么此再? 我笑而不...
    開封第一講書人閱讀 58,737評論 1 294
  • 正文 為了忘掉前任昔搂,我火速辦了婚禮,結(jié)果婚禮上输拇,老公的妹妹穿的比我還像新娘摘符。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,753評論 6 392
  • 文/花漫 我一把揭開白布逛裤。 她就那樣靜靜地躺著瘩绒,像睡著了一般。 火紅的嫁衣襯著肌膚如雪带族。 梳的紋絲不亂的頭發(fā)上锁荔,一...
    開封第一講書人閱讀 51,598評論 1 305
  • 那天,我揣著相機與錄音蝙砌,去河邊找鬼堕战。 笑死,一個胖子當(dāng)著我的面吹牛拍霜,可吹牛的內(nèi)容都是我干的嘱丢。 我是一名探鬼主播,決...
    沈念sama閱讀 40,338評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼祠饺,長吁一口氣:“原來是場噩夢啊……” “哼越驻!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起道偷,我...
    開封第一講書人閱讀 39,249評論 0 276
  • 序言:老撾萬榮一對情侶失蹤缀旁,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后勺鸦,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體并巍,經(jīng)...
    沈念sama閱讀 45,696評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,888評論 3 336
  • 正文 我和宋清朗相戀三年换途,在試婚紗的時候發(fā)現(xiàn)自己被綠了懊渡。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,013評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡军拟,死狀恐怖剃执,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情懈息,我是刑警寧澤肾档,帶...
    沈念sama閱讀 35,731評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站辫继,受9級特大地震影響怒见,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜姑宽,卻給世界環(huán)境...
    茶點故事閱讀 41,348評論 3 330
  • 文/蒙蒙 一遣耍、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧低千,春花似錦配阵、人聲如沸馏颂。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,929評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽救拉。三九已至,卻和暖如春瘫拣,著一層夾襖步出監(jiān)牢的瞬間亿絮,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,048評論 1 270
  • 我被黑心中介騙來泰國打工麸拄, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留派昧,地道東北人。 一個月前我還...
    沈念sama閱讀 48,203評論 3 370
  • 正文 我出身青樓拢切,卻偏偏與公主長得像蒂萎,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子淮椰,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,960評論 2 355

推薦閱讀更多精彩內(nèi)容