java 建造者模式的實際應用場景

開頭日常吹牛

我想大家在平時寫代碼的過程中肯定會去想這個類我怎麼寫簡潔點,或者後面容易維護些.畢竟項目一大起來,代碼量上去了以後,就算之前寫的時候有寫註釋,但回過頭來看總是需要再捋一遍,這就很浪費時間,畢竟大家都不想拿自己的下班時間來加班,程序員要懶一點好.這個時候設計模式的應用開始變得重要起來.在這裏給大家安利一點小小的設計模式

關於設計模式,社區裏已經很多人寫過,也有更清楚更詳細的介紹,總的來看,java有26種設計模式從類型上來說就有創建型,結構型.行爲型,再細分下去就是各個具體的模式了.但是常用的就那麼幾個,這其中就包括單例(我覺得這個應該是很多人第一個學會的),簡單工廠,建造者模式,這幾個算是創建型裏面比較經典的,其餘還有策略模式,適配器,裝飾者模式,也是比較常見的.

我覺得,這裏我們可以來一波小小的介紹.那我們給個平時的開發場景出來,方便大家來點假設性行爲.

開始假設性行爲

假設我現在要設計一個類,但是這個類裏面好幾個的成員變量,我不光要創建,我還要賦值.那這個,簡單啊,老夫操起鍵盤就是一頓啪啪啪啪啪啪啪,一分鐘不到,我把所有的類跟成員寫完,不光如此,我還附贈了一堆方法,包括get,set,toString,equals跟hashcode,於是我得意洋洋的說一聲,搞定!

/**
 * 示例類,房子
 * */
public class MyHome {
    private String mDoor;
    private String mKitchen;
    private String mToilet;
    private String mBathroom;
    private String mStudy;

    public String getDoor() {
        return mDoor;
    }
    public void setDoor(String mDoor) {
        this.mDoor = mDoor;
    }
    public String getKitchen() {
        return mKitchen;
    }
    public void setKitchen(String mKitchen) {
        this.mKitchen = mKitchen;
    }
    public String getToilet() {
        return mToilet;
    }
    public void setToilet(String mToilet) {
        this.mToilet = mToilet;
    }
    public String getBathroom() {
        return mBathroom;
    }
    public void setBathroom(String mBathroom) {
        this.mBathroom = mBathroom;
    }
    public String getStudy() {
        return mStudy;
    }
    public void setStudy(String mStudy) {
        this.mStudy = mStudy;
    }

    public MyHome() {
    }


    public void entering() {
        System.out.println("I entering in myHome");
    }
}

心裏頭喊着舒服!這年頭寫代碼就是那麼暢快,全賴IntelliJ開發的IDE,哼哼非常好用,寫完一個Alt+Insert,點點就完事了.

恩好,我得意洋洋的寫完,好,我現在我要創建這個類了,於是我一個new方法,new出了對象之後,就是一次次地set賦值,給成員變量賦值需要幾個就來幾個set,如果我成員變量更多的話呢,不怕,出來就是下面這樣

恩,我的代碼很牛逼.

        MyHome myHome = new MyHome();
        myHome.setBackyard();
        myHome.setBasement();
        myHome.setBathroom();
        myHome.setCourtyard();
        myHome.setDoor();
        myHome.setGate();
        myHome.setKitchen();
        myHome.setStudy();
        myHome.setSwimmingPond();
        myHome.setToilet();

然後,我感覺不行,要不我所有都在初始化的時候做了吧,這樣會不會比較舒服?想想又覺得自己更牛掰了.

public MyHome(String mDoor, String mGate, String mCourtyard, String mBackyard, String mSwimmingPond,
                  String mBasement, String mKitchen, String mToilet, String mBathroom, String mStudy) {
        this.mDoor = mDoor;
        this.mGate = mGate;
        this.mCourtyard = mCourtyard;
        this.mBackyard = mBackyard;
        this.mSwimmingPond = mSwimmingPond;
        this.mBasement = mBasement;
        this.mKitchen = mKitchen;
        this.mToilet = mToilet;
        this.mBathroom = mBathroom;
        this.mStudy = mStudy;
    }

    public MyHome() {
    }

那麼問題來了,我現在發現我好像不需要對某個屬性賦值,因爲賦了也用不着,算了吧.簡單,我弄多一個構造方法,不給它賦值就完事了,好,我又創建一個了一個特殊的構造方法.

public MyHome(String mCourtyard, String mBackyard, String mSwimmingPond, String mBasement, String mKitchen) {
        this.mCourtyard = mCourtyard;
        this.mBackyard = mBackyard;
        this.mSwimmingPond = mSwimmingPond;
        this.mBasement = mBasement;
        this.mKitchen = mKitchen;
    }

    public MyHome(String mToilet, String mBathroom, String mStudy) {
        this.mToilet = mToilet;
        this.mBathroom = mBathroom;
        this.mStudy = mStudy;
    }

或者我覺得這樣不行,一堆構造方法不好看,那可以啊,在有參的構造方法裏隨便給個數,或者賦值一個null,開心.

很好,我現在有兩個呢,三個呢,繼續隨便給數或者null?所以我要創建一個對象我要一堆的null作爲參數傳進去,那個畫面我真的不敢想象.像這樣

public class BuilderTest {
    public static void main(String[] args){
        MyHome myHome = new MyHome(null, "gate", null, null, null
                , null, null, null, null, null);
    }
}

分析

首先,這會導致冗餘的構造方法出現,如果我有10個成員變量,我就需要有無參的,還有剩下一堆隨意搭配的有參構造方法.真的是隨意搭配

其次,外部使用的時候就只需要這個對象,對外暴露的就只有類對象獲取,不需要關注其內部創建細節.也不符合類設計的原則

而現在我們的情況就像是,我買了房子後,我要自己對房子裏的一切再進行安排規劃最後入住。

換個思路

那既然這樣,我們乾脆讓售樓處瞭解我的需求,我說清楚,我只管買房子跟入住。從代碼上講也就是我不去主動控制這個類,我交由一個Builder類去創建,對外使用的時候我們就只需要new出一個Builder對象,然後調用其buildXXXMethod方法,最後一個build方法,創建這個目標類的對象

/**
 * 建造者抽象類
 *
 * Created by wangshaobin on 7/30/18.
 */

abstract class AbsBuilder<T> {
    /**
     * 建造者建造後要返回的對象
     * */
    abstract T build();

    /*
    * 相關操作
    * */
    abstract T planningDoor();
    abstract T planningKitchen();
    abstract T planningToilet();
    abstract T planningBathroom();
    abstract T planningStudy();
}
/**
 * 具體實現的建造者,核心類
 * */
class HomeBuilder extends AbsBuilder{

    private MyHome mMyHome = new MyHome();

    @Override
    MyHome build() {
        return mMyHome;
    }

    @Override
    HomeBuilder planningDoor(String door) {
        mMyHome.setDoor(door);
        return this;
    }

    @Override
    HomeBuilder planningKitchen(String kitchen) {
        mMyHome.setDoor(kitchen);
        return this;
    }

    @Override
    HomeBuilder planningToilet(String toilet) {
        mMyHome.setDoor(toilet);
        return this;
    }

    @Override
    HomeBuilder planningBathroom(String bathroom) {
        mMyHome.setDoor(bathroom);
        return this;
    }

    @Override
    HomeBuilder planningStudy(String study) {
        mMyHome.setDoor(study);
        return this;
    }
}
/**
 * 售樓處類
 *
 * Created by wangshaobin on 7/30/18.
 */

class HomeProvider {
    /**
     * 售樓處將用戶需求交給建造者,由建造者去創建房屋對象
     *
     * @param level 檔次
     * */
    static MyHome commandBuilder(String level) {
        HomeBuilder homeBuilder = new HomeBuilder();
        return homeBuilder
                .planningBathroom(level+"浴室")
//                .planningDoor(level+"門")
                .planningKitchen(level+"廚房")
                .planningStudy(level+"書房")
                .planningToilet(level+"廁所")
                .build();
    }
}

上面定義了一個建造者類負責接收我的需求,這樣一來我就把我的需求告訴售樓處即可,由建造者他們幫我規劃好,我只需要拿到房子並使用房子即可,在代碼中調用如下。

MyHome myHome = HomeProvider.commandBuilder("高級");
myHome.entering();

優缺點

先說說優點

首先是易於解耦,將產品本身與產品創建過程進行解耦,可以使用相同的創建過程來得到不同的產品。也就說細節依賴抽象。

其次易於精確控制對象的創建,將複雜產品的創建步驟分解在不同的方法中,使得創建過程更加清晰

最後是易於拓展,增加新的具體建造者無需修改原有類庫的代碼,易於拓展,符合“開閉原則“。

缺點方面

建造者模式所創建的產品一般具有較多的共同點,其組成部分相似;如果產品之間的差異性很大,則不適合使用建造者模式,因此其使用範圍受到一定的限制;如果產品的內部變化複雜,可能會導致需要定義很多具體建造者類來實現這種變化,導致系統變得很龐大。

應用場景

需要生成的產品對象有複雜的內部結構,這些產品對象具備共性;隔離複雜對象的創建和使用,並使得相同的創建過程可以創建不同的產品

 

以上就是我對建造者模式的介紹,有什麼說得不到位的還請大家批評指正

參考資料如下,如有冒犯,麻煩私信溝通:

https://blog.csdn.net/carson_ho/article/details/54910597

https://www.cnblogs.com/foryang/p/5849402.html

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章