設(shè)計(jì)模式之構(gòu)造者模式(建造者)

構(gòu)造者模式的定義

是指將一個(gè)復(fù)雜對象的構(gòu)造與它的表示分離白热,使同樣的構(gòu)建過程可以創(chuàng)建不同的表示,這樣的設(shè)計(jì)模式被稱為建造者模式东帅。
通俗的說,假如你要創(chuàng)建一個(gè)人類的對象,那么各個(gè)實(shí)例的屬性不同,也就是人的高矮胖瘦不一樣.這個(gè)時(shí)候可以考慮用構(gòu)造者模式.


構(gòu)造者模式的角色分類

  1. 具體的產(chǎn)品(要建造的東西)
  2. 抽象構(gòu)造者,一個(gè)包含創(chuàng)建產(chǎn)品各個(gè)子部件的抽象方法的接口,還要包含一個(gè)返回產(chǎn)品的方法.
  3. 具體構(gòu)造者,實(shí)現(xiàn)了抽象構(gòu)造者,重新其中的抽象方法.
  4. 指揮官,用來指揮如何生成產(chǎn)品.

構(gòu)造者模式的兩種分類

構(gòu)造者模式一共有四個(gè)角色,如果省掉其中的指揮者和抽象構(gòu)造者,只有一個(gè)具體的構(gòu)造者,那么久是簡單的構(gòu)造者模式.

正常構(gòu)造者模式

1,
假如我們要創(chuàng)建人類這個(gè)種產(chǎn)品.屬性有很多,我們隨意選幾個(gè)來做演示. 產(chǎn)品的信息如下:

public class Person {
    private String eyes; //眼睛
    private String mouth; //嘴
    private String legs; //腿
    
    // 省略get和set方法
}

2,
抽象構(gòu)造者,在這個(gè)抽象的類中,定義一些要用的方法

/**
 * 抽象構(gòu)造者
 */
public abstract class AbstractBuilder {

    //創(chuàng)建人類對象(產(chǎn)品)
    protected Person person = new Person();
    public abstract void buildEyes();
    public abstract void buildMouth();
    public abstract void buildLegs();

    //返回對象
    public Person getPerson(){
        return person;
    }
}

3,
具體構(gòu)造者

/**
 * 具體構(gòu)造者
 */
public class GirlPerson extends AbstractPersonBuilder {

    @Override
    public void buildEyes() {
        person.setEyes("大眼睛");
    }

    @Override
    public void buildMouth() {
        person.setMouth("小嘴巴");
    }

    @Override
    public void buildLegs() {
        person.setLegs("大長腿");
    }
}

4,
指揮者

/**
 * 指揮者
 */
public class Director {
    //抽象構(gòu)造者
    private AbstractPersonBuilder abstractPersonBuilder;

    public Director(AbstractPersonBuilder abstractPersonBuilder) {
        this.abstractPersonBuilder = abstractPersonBuilder;
    }
    //開始建造
    public Person instance(){
        abstractPersonBuilder.buildEyes();
        abstractPersonBuilder.buildMouth();
        abstractPersonBuilder.buildLegs();
        
        return abstractPersonBuilder.getPerson();
    }
}

5,
測試類

  public static void main(String[] args) {
        GirlPerson girlPerson = new GirlPerson();
        Director director = new Director(girlPerson);
        Person instance = director.instance();
        System.out.println(instance.toString());
        //log輸出
        //Person{eyes='大眼睛', mouth='小嘴巴', legs='大長腿'}
   }

也許到這里大家還沒有看出來,這么復(fù)雜的寫,有什么好處呢?
建造者(Builder)模式創(chuàng)建的是復(fù)雜對象抗俄,其產(chǎn)品的各個(gè)部分經(jīng)常面臨著劇烈的變化,但將它們組合在一起的算法卻相對穩(wěn)定音榜,所以它通常在以下場合使用。

  • 創(chuàng)建的對象較復(fù)雜捧弃,由多個(gè)部件構(gòu)成赠叼,各部件面臨著復(fù)雜的變化擦囊,但構(gòu)件間的建造順序是穩(wěn)定的。
  • 創(chuàng)建復(fù)雜對象的算法獨(dú)立于該對象的組成部分以及它們的裝配方式嘴办,即產(chǎn)品的構(gòu)建過程和最終的表示是獨(dú)立的瞬场。

假如我們現(xiàn)在需要重新添加一個(gè)男人的對象.那么只需要新建一個(gè)類繼承抽象構(gòu)造者即可.越是復(fù)雜的對象,用構(gòu)造模模式創(chuàng)建會很舒服.簡單的對象就算了.


簡單構(gòu)造者模式

這個(gè)構(gòu)造模式是除去了指揮者和抽象構(gòu)造者而產(chǎn)生的.
它的作用在于可以在創(chuàng)建對象的時(shí)候,可以通過內(nèi)類的一個(gè)構(gòu)造者.來靈活的創(chuàng)建.

public class User{
    String name;
    int age;
    String email;
    String address;
 
    public User(){
    }
    
    //想要有名字和郵箱的構(gòu)造器
    public User(String name, String email){
        this.name = name;
        this.email = email;
    }
 
    //想要有名字和地址的構(gòu)造器
    public User(String name, String address){
        this.name = name;
        this.address = address;
    }
}

在上面代碼中,很容易可以發(fā)現(xiàn)涧郊,在我們正常的需求下贯被,Java構(gòu)造器的編寫將會出問題,由于參數(shù)個(gè)數(shù)和類型一樣無法構(gòu)成重載底燎,所以這樣寫是不行的刃榨,那么Builder模式就是為了解決這種情況而出現(xiàn)的弹砚。

Builder模式的實(shí)現(xiàn)

下面我們一起來看一下Builder模式如何編寫的

public class User {
    String name;
    int age;
    String phone;
    String email;
    String address;
 
    //注意無參構(gòu)造器私有双仍,避免外界使用構(gòu)造器創(chuàng)建User對象
    private User() {
    }
 
    @Override
    public String toString() {
        return "User [name=" + name + ", age=" + age + ", phone=" + phone + ",                 
                email=" + email + ", address=" + address
                + "]";
    }
 
    public static class Builder {
    
        private String name;
        private int age;
        private String phone;
        private String email;
        private String address;
 
        public Builder() {
        }
        
        public Builder setName(String name) {
            this.name = name;
            return this;
        }
 
        public Builder setAge(int age) {
            this.age = age;
            return this;
        }
 
        public Builder setPhone(String phone) {
            this.phone = phone;
            return this;
        }
 
        public Builder setEmail(String email) {
            this.email = email;
            return this;
        }
 
        public Builder setAddress(String address) {
            this.address = address;
            return this;
        }
 
        public User build() {
            User user = new User();
            user.name = name;
            user.age = age;
            user.email = email;
            user.phone = phone;
            user.address = address;
            return user;
        }
    }
}

根據(jù)上面的代碼,我們可以看出來桌吃,就是在User內(nèi)部創(chuàng)建一個(gè)內(nèi)部類朱沃,并且擁有和User一樣的字段(屬性),并且提供SET方法茅诱,最重要的是要提供一個(gè)能夠返回User對象的方法(build)逗物,這樣才能通過Builder來創(chuàng)建User對象。

Builder設(shè)計(jì)模式還有一個(gè)好處瑟俭,那便是我們可以隨意組合輸入的參數(shù)翎卓,不僅避免了重載出錯(cuò)的問題,還不需要寫過多的構(gòu)造器摆寄。

下面我們一起看看寫完Builder模式類之后如何來調(diào)用:

public class UserTest {
    public static void main(String[] args) {
        User u = new User.Builder().setName("bob").setAge(22).build();
        System.out.println(u);
    }   
}

其它設(shè)計(jì)模式鏈接

設(shè)計(jì)模式之單例模式
設(shè)計(jì)模式之工廠模式

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末失暴,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子微饥,更是在濱河造成了極大的恐慌逗扒,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,198評論 6 514
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件欠橘,死亡現(xiàn)場離奇詭異矩肩,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)肃续,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,334評論 3 398
  • 文/潘曉璐 我一進(jìn)店門黍檩,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人始锚,你說我怎么就攤上這事建炫。” “怎么了疼蛾?”我有些...
    開封第一講書人閱讀 167,643評論 0 360
  • 文/不壞的土叔 我叫張陵肛跌,是天一觀的道長。 經(jīng)常有香客問我,道長衍慎,這世上最難降的妖魔是什么转唉? 我笑而不...
    開封第一講書人閱讀 59,495評論 1 296
  • 正文 為了忘掉前任,我火速辦了婚禮稳捆,結(jié)果婚禮上赠法,老公的妹妹穿的比我還像新娘。我一直安慰自己乔夯,他們只是感情好砖织,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,502評論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著末荐,像睡著了一般侧纯。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上甲脏,一...
    開封第一講書人閱讀 52,156評論 1 308
  • 那天眶熬,我揣著相機(jī)與錄音,去河邊找鬼块请。 笑死娜氏,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的墩新。 我是一名探鬼主播贸弥,決...
    沈念sama閱讀 40,743評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼海渊!你這毒婦竟也來了绵疲?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,659評論 0 276
  • 序言:老撾萬榮一對情侶失蹤切省,失蹤者是張志新(化名)和其女友劉穎最岗,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體朝捆,經(jīng)...
    沈念sama閱讀 46,200評論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡般渡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,282評論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了芙盘。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片驯用。...
    茶點(diǎn)故事閱讀 40,424評論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖儒老,靈堂內(nèi)的尸體忽然破棺而出蝴乔,到底是詐尸還是另有隱情,我是刑警寧澤驮樊,帶...
    沈念sama閱讀 36,107評論 5 349
  • 正文 年R本政府宣布薇正,位于F島的核電站片酝,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏挖腰。R本人自食惡果不足惜雕沿,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,789評論 3 333
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望猴仑。 院中可真熱鬧审轮,春花似錦、人聲如沸辽俗。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,264評論 0 23
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽崖飘。三九已至榴捡,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間坐漏,已是汗流浹背薄疚。 一陣腳步聲響...
    開封第一講書人閱讀 33,390評論 1 271
  • 我被黑心中介騙來泰國打工碧信, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留赊琳,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,798評論 3 376
  • 正文 我出身青樓砰碴,卻偏偏與公主長得像躏筏,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子呈枉,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,435評論 2 359

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