<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                企業??AI智能體構建引擎,智能編排和調試,一鍵部署,支持知識庫和私有化部署方案 廣告
                30.1 工廠方法模式VS建造者模式 工廠方法模式注重的是整體對象的創建方法,而建造者模式注重的是部件構建的過程,旨在通過一步一步地精確構造創建出一個復雜的對象。我們舉個簡單例子來說明兩者的差異,如要制造一個超人,如果使用工廠方法模式,直接產生出來的就是一個力大無窮、能夠飛翔、內褲外穿的超人;而如果使用建造者模式,則需要組裝手、頭、腳、軀干等部分,然后再把內褲外穿,于是一個超人就誕生了。純粹使用文字來描述比較枯燥,我們還是通過程序來更加清晰地認識兩者的差別。 30.1.1 按工廠方法建造超人 首先,按照工廠方法模式創建出一個超人,類圖如圖30-1所示。 ![](https://box.kancloud.cn/2016-08-14_57b0036cba8a6.jpg) 圖30-1 按工廠方法建造超人 類圖中我們按照年齡段把超人分為兩種類型:成年超人(如克拉克、超能先生)和未成年超人(如Dash、Jack)。這是一個非常正宗的工廠方法模式,定義一個產品的接口,然后再定義兩個實現,通過超人制造工廠制造超人。想想看我們對超人最大印象是什么?當然是他的超能力,我們以specialTalent(特殊天賦)方法來代表,先看抽象產品類,如代碼清單30-1所示。 代碼清單30-1 超人接口 public?interface?ISuperMan?{ ?????//每個超人都有特殊技能 ?????public?void?specialTalent(); } 產品的接口定義好了,我們再來看具體的產品。先看成年超人,很簡單,如代碼清單30-2所示。 代碼清單30-2 成年超人 public?class?AdultSuperMan?implements?ISuperMan?{ ?????//超能先生 ?????public?void?specialTalent()?{ ?????????????System.out.println("超人力大無窮"); ?????} } 未成年超人的代碼如代碼清單30-3所示。 代碼清單30-3 未成年超人 public?class?ChildSuperMan?implements?ISuperMan?{ ?????//超能先生的三個孩子 ?????public?void?specialTalent()?{ ?????????????System.out.println("小超人的能力是刀槍不入、快速運動"); ?????} } 產品都具備,那我們編寫一個工廠類,其意圖就是生產超人,具體是成年超人還是未成年超人,則由客戶端決定,如代碼清單30-4所示。 代碼清單30-4 超人制造工廠 public?class?SuperManFactory?{ ?????//定義一個生產超人的工廠 ?????public?static?ISuperMan?createSuperMan(String?type){ ?????????????//根據輸入參數產生不同的超人 ?????????????if(type.equalsIgnoreCase("adult")){ ?????????????????????//生產成人超人 ?????????????????????return?new?AdultSuperMan(); ?????????????}else?if(type.equalsIgnoreCase("child")){ ?????????????????????//生產未成年超人 ?????????????????????return?new?ChildSuperMan(); ?????????????}else{ ?????????????????????return?null; ?????????????} ?????} } 產品有了,工廠類也有了,剩下的工作就是開始生產超人。這也非常簡單,如代碼清單30-5所示。 代碼清單30-5 場景類 public?class?Client?{ ?????//模擬生產超人 ?????public?static?void?main(String[]?args)?{ ?????????????//生產一個成年超人 ?????????????ISuperMan?adultSuperMan?=?SuperManFactory.createSuperMan("adult"); ?????????????//展示一下超人的技能 ?????????????adultSuperMan.specialTalent(); ?????} } 建立了一個超人生產工廠,年復一年地生產超人,對于具體生產出的產品,不管是成年超人還是未成年超人,都是一個模樣:深藍色緊身衣、胸前S標記、內褲外穿,沒有特殊的地方。但是我們的目的達到了——生產出超人,拯救全人類,這就是我們的意圖。具體怎么生產、怎么組裝,這不是工廠方法模式要考慮的,也就是說,工廠模式關注的是一個產品整體,生產出的產品應該具有相似的功能和架構。 注意 通過工廠方法模式生產出對象,然后由客戶端進行對象的其他操作,但是并不代表所有生產出的對象都必須具有相同的狀態和行為,它是由產品所決定。 30.1.2 按建造者模式建造超人 我們再來看看建造者模式是如何生產超人的,如圖30-2所示。 ![](https://box.kancloud.cn/2016-08-14_57b0036cce92e.jpg) 圖30-2 按建造者模式生產超人 又是一個典型的建造者模式!哎,不對呀!通用模式上抽象建造者與產品類沒有關系呀!是的,我們當然可以加強了,我們在抽象建造者上使用了模板方法模式,每一個建造者都必須返回一個產品,但是產品是如何制造的,則由各個建造者自己負責。我們來看看程序,先看產品類,如代碼清單30-6所示。 代碼清單30-6 超人產品 public?class?SuperMan?{ ?????//超人的軀體 ?????private?String?body; ?????//超人的特殊技能 ?????private?String?specialTalent; ?????//超人的標志 ?????private?String?specialSymbol; ?????public?String?getBody()?{ ?????????????return?body; ?????} ?????public?void?setBody(String?body)?{ ?????????????this.body?=?body; ?????} ?????public?String?getSpecialTalent()?{ ?????????????return?specialTalent; ?????} ?????public?void?setSpecialTalent(String?specialTalent)?{ ?????????????this.specialTalent?=?specialTalent; ?????} ?????public?String?getSpecialSymbol()?{ ?????????????return?specialSymbol; ?????} ?????public?void?setSpecialSymbol(String?specialSymbol)?{ ?????????????this.specialSymbol?=?specialSymbol; ?????} } 超人這個產品是由三部分組成:軀體、特殊技能、身份標記,這就類似于電子產品,首先生產出一個固件,然后再安裝一個靈魂(軟件驅動),最后再打上產品標簽。完事了!一個嶄新的產品就誕生了!我們的超人也是這樣生產的,先生產一個普通的軀體,然后注入特殊技能,最后打上S標簽,一個超人生產完畢。我們再來看一下建造者的抽象定義,如代碼清單30-7所示。 代碼清單30-7 抽象建造者 public?abstract?class?Builder?{ ?????//定義一個超人的應用 ?????protected?final?SuperMan?superMan?=?new?SuperMan(); ?????//構建出超人的軀體 ?????public?void?setBody(String?body){ ?????????????this.superMan.setBody(body); ?????} ?????//構建出超人的特殊技能 ?????public?void?setSpecialTalent(String?st){ ?????????????this.superMan.setSpecialTalent(st); ?????} ?????//構建出超人的特殊標記 ?????public?void?setSpecialSymbol(String?ss){ ?????????????this.superMan.setSpecialSymbol(ss); ?????} ?????//構建出一個完整的超人 ?????public?abstract?SuperMan?getSuperMan(); } 一個典型的模板方法模式,超人的各個部件(軀體、靈魂、標志)都準備好了,具體怎么組裝則是由實現類來決定。我們先來看成年超人,如代碼清單30-8所示。 代碼清單30-8 成年超人建造者 public?class?AdultSuperManBuilder?extends?Builder?{ ?????@Override ?????public?SuperMan?getSuperMan()?{ ?????????????super.setBody("強壯的軀體"); ?????????????super.setSpecialTalent("會飛行"); ?????????????super.setSpecialSymbol("胸前帶S標記"); ?????????????return?super.superMan; ?????} } 怎么回事?在第11章中講解建造者模式的時候在產品中使用了模板方法模式,在這里怎么把模板方法模式遷移到建造者了?怎么會這樣?你是不是在發出這樣的疑問?別疑問了!設計模式只是提供了一個解決問題的意圖:復雜對象的構建與它的表示分離,而沒有具體定出一個設計模式必須是這樣的實現,必須是這樣的代碼,靈活運用模式才是其根本,別學死板了。 我們繼續看未成年超人的建造者,如代碼清單30-9所示。 代碼清單30-9 未成年超人建造者 public?class?ChildSuperManBuilder?extends?Builder?{ ?????@Override ?????public?SuperMan?getSuperMan()?{ ?????????????super.setBody("強壯的軀體"); ?????????????super.setSpecialTalent("刀槍不入"); ?????????????super.setSpecialSymbol("胸前帶小S標記"); ?????????????return?super.superMan; ?????} } 大家注意看我們這兩個具體的建造者,它們都關注了產品的各個部分,在某些應用場景下甚至會關心產品的構建順序,即使是相同的部件,裝配順序不同,產生的結果也不同,這也正是建造者模式的意圖:通過不同的部件、不同裝配產生不同的復雜對象。我們再來看導演類,如代碼清單30-10所示。 代碼清單30-10 導演類 public?class?Director?{ ?????//兩個建造者的應用 ?????private?static?Builder??adultBuilder?=?new?AdultSuperManBuilder(); ?????//未成年超人的建造者 ?????private?static?Builder?childBuilder?=?new?ChildSuperManBuilder(); ?????//建造一個成年、會飛行的超人 ?????public?static?SuperMan?getAdultSuperMan(){ ?????????????return?adultBuilder.getSuperMan(); ?????} ?????//建造一個未成年、刀槍不入的超人 ?????public?static?SuperMan?getChildSuperMan(){ ?????????????return?childBuilder.getSuperMan(); ?????} } 這很簡單,不多說了!看看場景類是如何調用的,如代碼清單30-11所示。 代碼清單30-11 場景類 public?class?Client?{ ?????public?static?void?main(String[]?args)?{ ?????????????//建造一個成年超人 ?????????????SuperMan?adultSuperMan?=?Director.getAdultSuperMan(); ?????????????//展示一下超人的信息 ?????????????adultSuperMan.getSpecialTalent(); ?????} } 這個場景類的寫法與工廠方法模式是相同的,但是你可以看到,在建立超人的過程中,建造者必須關注超人的各個部件,而工廠方法模式則只關注超人的整體,這就是兩者的區別。 30.1.3 最佳實踐 工廠方法模式和建造者模式都屬于對象創建類模式,都用來創建類的對象。但它們之間的區別還是比較明顯的。 ● 意圖不同 在工廠方法模式里,我們關注的是一個產品整體,如超人整體,無須關心產品的各部分是如何創建出來的;但在建造者模式中,一個具體產品的產生是依賴各個部件的產生以及裝配順序,它關注的是“由零件一步一步地組裝出產品對象”。簡單地說,工廠模式是一個對象創建的粗線條應用,建造者模式則是通過細線條勾勒出一個復雜對象,關注的是產品組成部分的創建過程。 ● 產品的復雜度不同 工廠方法模式創建的產品一般都是單一性質產品,如成年超人,都是一個模樣,而建造者模式創建的則是一個復合產品,它由各個部件復合而成,部件不同產品對象當然不同。這不是說工廠方法模式創建的對象簡單,而是指它們的粒度大小不同。一般來說,工廠方法模式的對象粒度比較粗,建造者模式的產品對象粒度比較細。 兩者的區別有了,那在具體的應用中,我們該如何選擇呢?是用工廠方法模式來創建對象,還是用建造者模式來創建對象,這完全取決于我們在做系統設計時的意圖,如果需要詳細關注一個產品部件的生產、安裝步驟,則選擇建造者,否則選擇工廠方法模式。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看