設(shè)計模式之建造者模式

建造者模式

為什么使用及建造者模式

就以《大話設(shè)計模式》中的案例來說吧,中國人做飯,同一個魚香肉絲,不同的廚師做出來就很容易不同。而且有可能這個缺鹽、那個缺醋,怎么么辦呢?可以向麥當(dāng)勞學(xué)習(xí)?;旧先袊柠湲?dāng)勞都是一個口味,為什么?因為麥當(dāng)勞餐飲流程基本上被寫死,這個肉炸幾分鐘,這個餅烤幾分鐘。。。這樣做出來的飯自然味道上都大差不差。因此從麥當(dāng)勞的經(jīng)驗來看,應(yīng)當(dāng)給小廚子定一個做魚香肉絲的流程,一個步驟接著另一個步驟,至于每個步驟具體怎么做,那肯定要靠小廚子自己以免廚師忘記。

而且這還不夠,試想一下我們吃魚香肉絲的場景,經(jīng)常有人對老板說多放點辣、少放點辣之類的、把菜炒老點,這也正常嘛,畢竟每個人的口味不一樣。但如果只寫一個統(tǒng)一的步驟,那么小廚子在做飯的時候就不好控制。怎么辦呢?專門找一個人,就叫他廚師長吧,負責(zé)指揮小廚子們干活,在分配任務(wù)的時候把顧客的特殊需求告訴響應(yīng)的小廚子。并且,因為小廚子手藝不是太好,每人就先做一個固定口味的魚香肉絲。

代碼樣例

我說的比較混亂,結(jié)合和具體的代碼可能會好點:

整體步驟Procedure.java

package builder;

/**
 * @author: OnlyOne
 * @create: 2020-08-26 18:34
 * @description: 做魚香肉絲的整體步驟,抽象建造者類,強制規(guī)定做魚香肉絲有哪些步驟
 **/
public abstract class Procedure {

    /**
     * @description: 第一步:放油
     * @author: OnlyOne
     * @create: 2020/8/26
     * @param: []       
     * @return void
     **/
    public abstract void putOil();

    /**
     * @description: 第二部:放鹽
     * @author: OnlyOne
     * @create: 2020/8/26
     * @param: []       
     * @return void
     **/
    public abstract void putSalt();

    /**
     * @description: 第三部:炒菜
     * @author: OnlyOne
     * @create: 2020/8/26
     * @param: []       
     * @return void
     **/
    public abstract void hotVegetables();

    /**
     * @description: 上菜
     * @author: OnlyOne
     * @create: 2020/8/26
     * @param: []
     * @return YuXiangRouSi
     **/
    public abstract YuXiangRouSi Serve();
}

魚香肉絲:YuXiangRouSi.java

package builder;

import java.util.ArrayList;
import java.util.List;

/**
 * @author: OnlyOne
 * @create: 2020-08-26 18:29
 * @description: 產(chǎn)品類,一個產(chǎn)品分為A,B兩部分
 **/
public class YuXiangRouSi {

    List<String> steps = new ArrayList<String>();

    public void add(String step) {
        steps.add(step);
    }

    public void show() {
        System.out.println("這盤菜的制作過程:");
        for (String step :
                steps) {
            System.out.println(step);
        }
    }

}

廚師長:HeadCooker.java

package builder;

/**
 * @author: OnlyOne
 * @create: 2020-08-26 18:42
 * @description: 指揮者類,廚師長,根據(jù)顧客的不同需求做不同版本的魚香肉絲
 **/
public class HeadCooker {

    /**
     * @description: 廚師長指揮小廚子們做飯
     * @author: OnlyOne
     * @create: 2020/8/26
     * @param: [procedure]       
     * @return void
     **/
    public void direct(Procedure procedure) {
        //第一步,放油
        procedure.putOil();
        //第二部,放鹽
        procedure.putSalt();
        //第三部,炒菜
        procedure.hotVegetables();
        //上菜
        procedure.Serve();
    }
}

小廚子A:CookerA.java

package builder;

/**
 * @author: OnlyOne
 * @create: 2020-08-26 18:38
 * @description: 具體建造者類,小廚子A,專門做魚香肉絲清淡版,少油、少鹽、菜生
 **/
public class CookerA extends Procedure {

    private YuXiangRouSi yuXiangRouSi = new YuXiangRouSi();

    /**
     * @return void
     * @description: 第一步:放油
     * @author: OnlyOne
     * @create: 2020/8/26
     * @param: []
     **/
    @Override
    public void putOil() {
        yuXiangRouSi.add("放入少量的油");
    }

    /**
     * @return void
     * @description: 第二部:放鹽
     * @author: OnlyOne
     * @create: 2020/8/26
     * @param: []
     **/
    @Override
    public void putSalt() {
        yuXiangRouSi.add("放入少量的鹽");
    }

    /**
     * @return void
     * @description: 第三部:炒菜
     * @author: OnlyOne
     * @create: 2020/8/26
     * @param: []
     **/
    @Override
    public void hotVegetables() {
        yuXiangRouSi.add("小火翻炒");
    }

    /**
     * @return YuXiangRouSi
     * @description: 上菜
     * @author: OnlyOne
     * @create: 2020/8/26
     * @param: []
     **/
    @Override
    public YuXiangRouSi Serve() {
        return yuXiangRouSi;
    }
}

小廚子B:CookerB.java

package builder;

/**
 * @author: OnlyOne
 * @create: 2020-08-26 18:38
 * @description: 具體建造者類,小廚子B,專門做魚香肉絲爽辣版,多油、多鹽,菜熟
 **/
public class CookerB extends Procedure {

    private YuXiangRouSi yuXiangRouSi = new YuXiangRouSi();

    /**
     * @return void
     * @description: 第一步:放油
     * @author: OnlyOne
     * @create: 2020/8/26
     * @param: []
     **/
    @Override
    public void putOil() {
        yuXiangRouSi.add("放入大量的油");
    }

    /**
     * @return void
     * @description: 第二部:放鹽
     * @author: OnlyOne
     * @create: 2020/8/26
     * @param: []
     **/
    @Override
    public void putSalt() {
        yuXiangRouSi.add("放入大量的鹽");
    }

    /**
     * @return void
     * @description: 第三部:炒菜
     * @author: OnlyOne
     * @create: 2020/8/26
     * @param: []
     **/
    @Override
    public void hotVegetables() {
        yuXiangRouSi.add("大火翻炒");
    }

    /**
     * @return YuXiangRouSi
     * @description: 上菜
     * @author: OnlyOne
     * @create: 2020/8/26
     * @param: []
     **/
    @Override
    public YuXiangRouSi Serve() {
        return yuXiangRouSi;
    }

}

顧客:Main.java

package builder;

/**
 * @author: OnlyOne
 * @create: 2020-08-26 18:43
 * @description: 客戶端
 **/
public class Main {
    public static void main(String[] args) {
        HeadCooker headCooker = new HeadCooker();
        Procedure cookerA = new CookerA();
        Procedure cookerB = new CookerB();

        // 顧客點餐了
        System.out.println("顧客一:來一份清淡版的魚香肉絲");
        // 廚師長指揮
        headCooker.direct(cookerA);
        // 上菜
        YuXiangRouSi yuXiangRouSiA = cookerA.Serve();
        // 查看做飯步驟
        yuXiangRouSiA.show();

        System.out.println("**************************************");

        System.out.println("顧客二:來一份爽辣版的魚香肉絲");
        headCooker.direct(cookerB);
        YuXiangRouSi yuXiangRouSiB = cookerB.Serve();
        yuXiangRouSiB.show();

    }
}

運行結(jié)果:

image-20200826211119050

個人思考

在使用建造者模式的時候,我明顯感覺建造者模式與之前學(xué)過的一種設(shè)計模式很像,即模板方法。

模板方法是在抽象類中定義步驟,讓子類去繼承,關(guān)鍵之處在于相同的方法就在抽象類中實現(xiàn),而不相同的方法,就讓其子類各自實現(xiàn)。相對而言比較簡單

建造者模式與,模板方法很想,我認為它是在模板方法的基礎(chǔ)上增加了一個Director(指揮者),這個Director可以設(shè)置步驟的執(zhí)行順序。

目前也是剛剛接觸建造者模式,對其理解還比較膚淺,甚至有些地方理解錯誤。如果有哪里理解不到位的地方,還請指出。收到后必定會在第一時間進行改正,本篇博客也會持續(xù)更新,有新的理解會及時補充

本文純原創(chuàng),寫作不易,如果了幫到您,請點贊、轉(zhuǎn)發(fā)、收藏!杜絕抄襲,轉(zhuǎn)載請注明來源!

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容