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

                ThinkChat2.0新版上線,更智能更精彩,支持會話、畫圖、視頻、閱讀、搜索等,送10W Token,即刻開啟你的AI之旅 廣告
                ### 一、模式定義 簡單工廠模式(Simple Factory Pattern):又稱為靜態工廠方法(Static Factory Method)模式,它屬于類創建型模式(同屬于創建型模式的還有工廠方法模式,抽象工廠模式,單例模式,建造者模式)。在簡單工廠模式中,可以根據參數的不同返回不同類的實例。簡單工廠模式專門定義一個類來負責創建其他類的實例,被創建的實例通常都具有共同的父類。 ### 二、模式結構 ![這里寫圖片描述](https://box.kancloud.cn/2016-04-20_571758163b57c.jpg "") 從上圖可以看出,簡單工廠模式由三部分組成:具體工廠、具體產品和抽象產品。 - 工廠類(Creator)角色:擔任這個角色的是簡單工廠模式的核心,含有與應用緊密相關的商業邏輯。工廠類在客戶端的直接調用下創建產品對象,它往往由一個具體Java類實現。 - 抽象產品(AbstractProduct)角色:擔任這個角色的類是由簡單工廠模式所創建的對象的父類,或它們共同擁有的接口。抽象產品角色可以用一個Java接口或者Java抽象類實現。 - 具體產品(ConcreteProduct)角色:簡單工廠模式所創建的任何對象都是這個角色的實例,具體產品角色由一個具體Java類實現。 ### 三、模式動機 使用簡單工廠模式可以將產品的“消費”和生產完全分開,客戶端只需要知道自己需要什么產品,如何來使用產品就可以了,具體的產品生產任務由具體的工廠類來實現。工廠類根據傳進來的參數生產具體的產品供消費者使用。這種模式使得更加利于擴展,當有新的產品加入時僅僅需要在工廠中加入新產品的構造就可以了。 ### 四、實例分析 話說有一位土豪,他家有三輛汽車——Benz奔馳、Bmw寶馬、Audi奧迪,還雇了司機為他開車。不過,土豪坐車時總是怪怪的:上Benz車后跟司機說“開奔馳車!”坐上Bmw后他說“開寶馬車!”,坐上Audi說“開奧迪車!”。你一定說:這人有病!直接說開車不就行了?! 而當把土豪的行為放到我們程序設計中來時,會發現這是一個普遍存在的現象。幸運的是,這種有病的現象在OO(面向對象)語言中可以避免了。下面就以Java語言為例來講解一下如何避免這種問題。 下面就是剛剛的故事所描述的場景,這段代碼真的是有病啊。 這個是Audi車的類,在這個類中有driveAudi的方法。 ~~~ package com.myfactory.pre1; public class Audi { public Audi(){ System.out.println("Create a Audi"); } public void driveAudi(){ System.out.println("Audi start engine"); } } ~~~ 這個是Benz車的類,在這個類中有driveBenz 的方法。 ~~~ package com.myfactory.pre1; public class Benz { public Benz(){ System.out.println("Create a Benz"); } public void driveBenz(){ System.out.println("Benz start engine"); } } ~~~ 這個是Bmw車的類,在這個類中有driveBmw 的方法。 ~~~ package com.myfactory.pre1; public class Bmw { public Bmw(){ System.out.println("Create a Bmw"); } public void driveBmw(){ System.out.println("Bmw start engine"); } } ~~~ 主程序調用剛剛創建的三輛車的類。 ~~~ package com.myfactory.pre1; public class Main { public static void main(String[] args) { //今天想做奧迪車 Audi audi = new Audi(); //開奧迪車 audi.driveAudi(); } } ~~~ 學過程序設計的人都能看出來上邊這段代碼的結構非常的不好。有兩點,一是,不管是Audi,Benz還是Bmw,大家不都是車嗎,為什么不直接創建一個Car的父類,然后讓其他的汽車的子類來繼承呢,二是,不管是什么車肯定都能開啊,干嘛要分那么清楚呢,直接在父類中寫一個drive方法讓子類來實現不就好了,如果每輛汽車都有自己名字命名的drive方法,那如果main中稍微寫錯一點程序就跑不起來了。 所有針對以上的問題我們可以做如下的優化。 創建了一個新的類Car,作為所有汽車的父類,定義了一個抽象的drive方法,具體的實現由子類來實現。 ~~~ package com.myfactory.pre2; public abstract class Car { abstract void drive(); } ~~~ 這是改進后的Audi類實現了父類的drive方法。 ~~~ package com.myfactory.pre2; public class Audi extends Car{ public Audi(){ System.out.println("Create a Audi"); } public void drive(){ System.out.println("Audi start engine"); } } ~~~ Benz和Bmw都是類似的,這里為了節約篇幅我就不再貼出來了,最后回復上完整的源碼。 這是改進后的新客戶端: ~~~ package com.myfactory.pre2; public class Main { public static void main(String[] args) { //今天想做奧迪車 Car car = new Audi(); //開車 car.drive(); } } ~~~ 這個方案看似完美但其實還是存在巨大的隱患。我提供對的實例是比較簡單的,但實際應用中創建對象時可能不是一句話就能解決的事,比如創建奧迪車時需要發動機的型號,輪胎的大小,玻璃的尺寸,并且尺寸可能是由一系列復雜的運算計算出來的,所以如果把創建對象的任務放到客戶端中,就是使客戶端顯得非常的臃腫,所以我們可以借助簡單工廠模式進行改進。 我們創建一個工廠類,這個工廠類專門負責建造各種汽車,代碼如下: ~~~ package com.myfactory.simplefactory; public class Driver { public static Car getCar(String type) throws Exception{ if(type.equals("Benz")){ return new Benz(); }else if(type.equals("Audi")){ return new Audi(); }else if(type.equals("Bmw")){ return new Bmw(); }else{ throw new Exception(); } } } ~~~ 各種汽車的類還是不變,這里不再貼出代碼,此時的客戶端發生了變化。 ~~~ package com.myfactory.simplefactory; public class Main { public static void main(String[] args) throws Exception { //今天想做奧迪車 Car car = Driver.getCar("Audi"); //開車 car.drive(); } } ~~~ 我們看到,土豪不再需要自己new對象了,而是告訴Driver類今天我想要開什么車,Driver就會自動的將想要的汽車創建出來,然后土豪坐在車里只需要說開車就好了,這樣不就符合我們的邏輯了嗎。 在上面的那個例子中,Driver類就是我們說的工廠,他用if-else語句來判斷需要創建什么類型的對象(當然也可以使用switch語句),這就是我們一直說的簡單工廠模式。 ### 五、模式優點 - 工廠類含有必要的判斷邏輯,可以決定在什么時候創建哪一個產品類的實例,客戶端可以免除直接創建產品對象的責任,而僅僅“消費”產品;簡單工廠模式通過這種做法實現了對責任的分割,它提供了專門的工廠類用于創建對象。 - 客戶端無須知道所創建的具體產品類的類名,只需要知道具體產品類所對應的參數即可,對于一些復雜的類名,通過簡單工廠模式可以減少使用者的記憶量。 - 通過引入配置文件,可以在不修改任何客戶端代碼的情況下更換和增加新的具體產品類,在一定程度上提高了系統的靈活性。 - 當需要引入新的產品是不需要修改客戶端的代碼,只需要添加相應的產品類并修改工廠類就可以了,所以說從產品的角度上簡單工廠模式是符合“開-閉”原則的。 ### 六、模式缺點 - 由于工廠類集中了所有產品創建邏輯,工廠類一般被我們稱作“全能類”或者“上帝類”,因為所有的產品創建他都能完成,這看似是好事,但仔細想想是有問題的。比如全國上下所有的事情都有國家主義一個人干會不會有問題,當然有!一旦不能正常工作,整個系統都要受到影響。 - 使用簡單工廠模式將會增加系統中類的個數,在一定程序上增加了系統的復雜度和理解難度。 - 系統擴展困難,一旦添加新產品就不得不修改工廠邏輯,在產品類型較多時,有可能造成工廠邏輯過于復雜,不利于系統的擴展和維護。所以說從工廠的角度來說簡單工廠模式是不符合“開-閉”原則的。 - 簡單工廠模式由于使用了靜態工廠方法,造成工廠角色無法形成基于繼承的等級結構。 ### 七、適用場景 在以下情況下可以使用簡單工廠模式: 1、工廠類負責創建的對象比較少:由于創建的對象較少,不會造成工廠方法中的業務邏輯太過復雜。 2、客戶端只知道傳入工廠類的參數,對于如何創建對象不關心:客戶端既不需要關心創建細節,甚至連類名都不需要記住,只需要知道類型所對應的參數。 ### 八、模式在JDK中的應用 JDK類庫中廣泛使用了簡單工廠模式,如工具類java.text.DateFormat,它用于格式化一個本地日期或者時間。 ~~~ public final static DateFormat getDateInstance(); public final static DateFormat getDateInstance(int style); public final static DateFormat getDateInstance(int style,Locale locale); ~~~ 源碼下載:[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>

                              哎呀哎呀视频在线观看