<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>

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                ### 一、模式定義 工廠方法模式(Factory Method Pattern)又稱為工廠模式,也叫虛擬構造器(Virtual Constructor)模式或者多態工廠(Polymorphic Factory)模式,它屬于類創建型模式。在工廠方法模式中,工廠父類負責定義創建產品對象的公共接口,而工廠子類則負責生成具體的產品對象,這樣做的目的是將產品類的實例化操作延遲到工廠子類中完成,即通過工廠子類來確定究竟應該實例化哪一個具體產品類。 ### 二、模式結構 ![這里寫圖片描述](https://box.kancloud.cn/2016-04-20_571758164f814.jpg "") 我們可以看到工廠方法模式一共分為四個部分: - 抽象工廠(AbstractCreator)角色:擔任這個角色的是工廠方法模式的核心,它是與應用程序無關的。任何在模式中創建對象的工廠類必須繼承或者實現這個接口,在實際的系統中,這個角色常常有Java抽象類來實現。 - 具體工廠(ConcreteCreator)角色:擔任這個角色的是實現了抽象工廠接口的具體Java類。具體工廠角色含有與應用密切相關的邏輯,并且受到應用程序的調用以創建產品對象。 - 抽象產品(AbstractProduct)角色:工廠方法模式所創建的對象的超類型,也就是產品對象的共同父類或共同擁有的接口。在實際應用中這個角色常常由Java的抽象類來實現。 - 具體產品(ConcreteProduct)角色:這個角色實現了抽象產品角色所聲明的接口,工廠方法所創建的每一個對象都是某個具體產品角色的實例。 ### 三、模式動機 1、解決簡單工廠模式中存在的“上帝類”的問題,將具體的生產任務放到子類中去。 2、解決簡單工廠模式工廠角度不符合“開-閉”原則的問題。 3、解決簡單工廠模式不能使用繼承的問題。 ![這里寫圖片描述](https://box.kancloud.cn/2016-04-20_57175816640af.jpg "") ### 四、實例分析 我們繼續來分析上一篇博客中土豪開車的問題,我們使用了簡單工廠模式后,程序好像已經很合理了,并且從實際生活來看也是比較符合邏輯的。但是可能會存在以下的問題。 1、如果土豪家里又買了很多車,那么Driver(工廠類)將會非常大,每次買一輛新的車都需要在這個工廠類中添加一個if-else語句,如果有的車壞了不能開了,還需要將對應的if-else語句刪除,所以很麻煩,也不符合“開-閉”原則。 2、所有的產品創建都集中在Driver類中,一旦寫錯一個標點,所有的產品便都不能生產了。(可以想象成,只有一位司機師傅,這位司機師傅會開所有的車,一旦這一位司機師傅生病了,那么所有的汽車就都不能開了)。 所以我們可以使用工廠方法模式以下的改進。 首先,定義一個抽象的工廠類(Driver),這個抽象工廠類中有定義好的抽象方法getCar();用來告訴具體的工廠如何來獲得汽車。 ~~~ package com.myfactory.factory; public abstract class Driver { public abstract Car getCar(); } ~~~ 然后,每一種車都配一個專門的司機,這個司機只負責或者一種車。 ~~~ package com.myfactory.factory; public class BenzDriver extends Driver{ public Car getCar() { return new Benz(); } } ~~~ 這里只寫了Benz車的類,其他的車的類和這個類基本相同,不再貼出代碼,最后會附上源碼。 在客戶端中,創建對應的Driver類,讓特定的Driver來生產特定的汽車。 ~~~ package com.myfactory.factory; public class Main { public static void main(String[] args) throws Exception { //奔馳車司機 Driver driver = new BenzDriver(); //今天想做奧迪車 Car car = driver.getCar(); //開車 car.drive(); } } ~~~ 通過改進,我們看到不再存在“上帝類”,有具體的工廠類來負責生產特定的產品,以后想要添加新的車的時候不必修改現有的工廠和產品的代碼,只需要添加新的產品類和具體工廠類就可以了,不管是產品角度還是工廠角度都更加符合“開-閉”原則。 ### 五、模式優點 - 在工廠方法模式中,工廠方法用來創建客戶所需要的產品,同時還向客戶隱藏了哪種具體產品類將被實例化這一細節,用戶只需要關心所需產品對應的工廠,無須關心創建細節,甚至無須知道具體產品類的類名。 - 基于工廠角色和產品角色的多態性設計是工廠方法模式的關鍵。它能夠使工廠可以自主確定創建何種產品對象,而如何創建這個對象的細節則完全封裝在具體工廠內部。工廠方法模式之所以又被稱為多態工廠模式,是因為所有的具體工廠類都具有同一抽象父類。 - 使用工廠方法模式的另一個優點是在系統中加入新產品時,無須修改抽象工廠和抽象產品提供的接口,無須修改客戶端,也無須修改其他的具體工廠和具體產品,而只要添加一個具體工廠和具體產品就可以了。這樣,系統的可擴展性也就變得非常好,完全符合“開閉原則”。 ### 六、模式缺點 - 在添加新產品時,需要編寫新的具體產品類,而且還要提供與之對應的具體工廠類,系統中類的個數將成對增加,在一定程度上增加了系統的復雜度,有更多的類需要編譯和運行,會給系統帶來一些額外的開銷。 - 由于考慮到系統的可擴展性,需要引入抽象層,在客戶端代碼中均使用抽象層進行定義,增加了系統的抽象性和理解難度,且在實現時可能需要用到DOM、反射等技術,增加了系統的實現難度。 ### 七、適用場景 在以下情況下可以使用工廠方法模式: 1、一個類不知道它所需要的對象的類:在工廠方法模式中,客戶端不需要知道具體產品類的類名,只需要知道所對應的工廠即可,具體的產品對象由具體工廠類創建;客戶端需要知道創建具體產品的工廠類。 2、一個類通過其子類來指定創建哪個對象:在工廠方法模式中,對于抽象工廠類只需要提供一個創建產品的接口,而由其子類來確定具體要創建的對象,利用面向對象的多態性和里氏代換原則,在程序運行時,子類對象將覆蓋父類對象,從而使得系統更容易擴展。 3、將創建對象的任務委托給多個工廠子類中的某一個,客戶端在使用時可以無須關心是哪一個工廠子類創建產品子類,需要時再動態指定,可將具體工廠類的類名存儲在配置文件或數據庫中。 ### 八、模式在JDK中的應用 1、Object中的toString方法:Object僅僅定義了返回String,由Object的子類來決定如何生成這個字符串。 2、抽象類java.util.Calendar的getInstance方法將根據不同的情況返回不同的Calendar子類的對象。 源碼下載:[http://download.csdn.net/detail/xingjiarong/9294193](http://download.csdn.net/detail/xingjiarong/9294193)
                  <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>

                              哎呀哎呀视频在线观看