<kbd id="5sdj3"></kbd>
<th id="5sdj3"></th>

  • <dd id="5sdj3"><form id="5sdj3"></form></dd>
    <td id="5sdj3"><form id="5sdj3"><big id="5sdj3"></big></form></td><del id="5sdj3"></del>

  • <dd id="5sdj3"></dd>
    <dfn id="5sdj3"></dfn>
  • <th id="5sdj3"></th>
    <tfoot id="5sdj3"><menuitem id="5sdj3"></menuitem></tfoot>

  • <td id="5sdj3"><form id="5sdj3"><menu id="5sdj3"></menu></form></td>
  • <kbd id="5sdj3"><form id="5sdj3"></form></kbd>

    設計模式之工廠模式

    共 17999字,需瀏覽 36分鐘

     ·

    2021-03-26 14:11

    一、工廠模式簡介

    1、使用工廠模式的好處

    工廠模式是創(chuàng)建型模式中最典型的模式,主要作用是用來創(chuàng)建對象,使用工廠模式替代new操作有如下幾個好處:
    1:解耦,把創(chuàng)建對象的工作和使用對象的工作分開,比如我們想使用對象A,我們無需關心對象A是如何創(chuàng)建的,直接去工廠獲取就行。
    2:對于構(gòu)造函數(shù)很復雜的對象,可以很好地對外層屏蔽代碼的復雜性
    3:把初始化實例的工作放到工廠里進行統(tǒng)一管理,使代碼更容易維護。
    4:修改代碼時不會引起太大的變動,如果想改代碼的話,只需要改一處即可,良好的擴展性。
    5:減少代碼量,如果構(gòu)造方法比較復雜,有很多很多個構(gòu)造函數(shù),需要一連串的代碼創(chuàng)建對象,如果使用new就會造成很多重復的代碼。

    2、用一個例子說明使用工廠模式相對于new操作的優(yōu)勢

    下面我們分別從使用new創(chuàng)建對象和工廠模式兩種方面講解,幫助大家理解工廠模式的優(yōu)勢。

    需求1:有三個用戶,需要定制相同的藍莓黑巧動物奶油做的蛋糕。使用new創(chuàng)建對象:

    // 蛋糕類
    public class Cake {
        private String fruit;// 配料:水果
        private String chocolate;// 配料:巧克力
        private String cream;// 配料:奶油

        public Cake(String fruit, String chocolate, String cream){
            this.fruit = fruit;
            this.chocolate = chocolate;
            this.cream = cream;
        }
    }
    public class Test1 {
        public static void main(String[] args) {
            // 用戶A訂了一個藍莓黑巧動物奶油做的蛋糕
            Cake cake1 = new Cake("藍莓""黑巧克力""動物奶油");
            // 用戶B訂了一個藍莓黑巧動物奶油做的蛋糕
            Cake cake2 = new Cake("藍莓""黑巧克力""動物奶油");
            // 用戶C訂了一個藍莓黑巧動物奶油做的蛋糕
            Cake cake3 = new Cake("藍莓""黑巧克力""動物奶油");
        }
    }

    工廠模式:

    // 蛋糕工廠
    public class CakeFactory {
        public Cake createCake(){
            return new Cake("藍莓""黑巧克力""動物奶油");
        }
    }
    public class Test2 {
        public static void main(String[] args) {
            CakeFactory cakeFactory = new CakeFactory();
            // 用戶A訂了一個藍莓黑巧動物奶油做的蛋糕
            cakeFactory.createCake();
            // 用戶B訂了一個藍莓黑巧動物奶油做的蛋糕
            cakeFactory.createCake();
            // 用戶C訂了一個藍莓黑巧動物奶油做的蛋糕
            cakeFactory.createCake();
        }
    }

    需求2;這三個用戶想要在蛋糕中加入一種堅果,如果使用new創(chuàng)建對象,需要修改三個new操作,使用工廠模式,只需修改工廠中的new操作即可,改動更少,帶來錯誤的可能性就越少。 使用new創(chuàng)建對象:

    // 蛋糕類
    public class Cake {
        private String fruit;// 配料:水果
        private String chocolate;// 配料:巧克力
        private String cream;// 配料:奶油
        private String nut;// 配料:堅果

        public Cake(String fruit, String chocolate, String cream, String nut){
            this.fruit = fruit;
            this.chocolate = chocolate;
            this.cream = cream;
            this.nut = nut;
        }
    }
    public class Test1 {
        public static void main(String[] args) {
            // 用戶A訂了一個藍莓黑巧動物奶油榛子做的蛋糕
            Cake cake1 = new Cake("藍莓""黑巧克力""動物奶油""榛子");
            // 用戶B訂了一個藍莓黑巧動物奶油榛子做的蛋糕
            Cake cake2 = new Cake("藍莓""黑巧克力""動物奶油""榛子");
            // 用戶C訂了一個藍莓黑巧動物奶油榛子做的蛋糕
            Cake cake3 = new Cake("藍莓""黑巧克力""動物奶油""榛子");
        }
    }

    工廠模式:

    // 蛋糕工廠
    public class CakeFactory {
        public Cake createCake(){
            return new Cake("藍莓""黑巧克力""動物奶油""榛子");
        }
    }
    public class Test2 {
        public static void main(String[] args) {
            CakeFactory cakeFactory = new CakeFactory();
            // 用戶A訂了一個藍莓黑巧動物奶油榛子做的蛋糕
            cakeFactory.createCake();
            // 用戶B訂了一個藍莓黑巧動物奶油榛子做的蛋糕
            cakeFactory.createCake();
            // 用戶C訂了一個藍莓黑巧動物奶油榛子做的蛋糕
            cakeFactory.createCake();
        }
    }
    3、工廠模式分類

    工廠模式,包含三種情況,簡單工廠工廠方法、抽象工廠,下面我們就來一一介紹一下。

    我相信大家都有這樣的困惑,目前我所在的項目都在程序開發(fā)的過程中,還是有很多的new()操作出現(xiàn)在程序中,并沒有通過工廠來創(chuàng)建對象,一方面可能是因為我們自身比較懶,不規(guī)范項目的編碼形式,另外一方面也是由于項目的進度比較緊,沒有那么多的時間去完成工廠的統(tǒng)一創(chuàng)建。

    二、簡單工廠

    我們將用幾個例子來逐步講解簡單工廠、工廠方法、抽象工廠,下面我們就開始吧。

    1、簡單工廠示例

    小明在老家開了一家飲品店,提供多種飲品,當有顧客來店里,只需要和服務員說他想喝哪種飲料,服務員便可提供哪種飲料,這就是簡單工廠模式,服務員就是這個簡單工廠。

    // 抽象飲料
    public abstract class Drink {
        public abstract void desc();
    }

    // 蘋果汁
    public class AppleDrink extends Drink {
        @Override
        public void desc() {
            System.out.println("這是一杯蘋果汁!");
        }
    }

    // 葡萄汁
    public class GrapeDrink extends Drink {
        @Override
        public void desc() {
            System.out.println("這是一杯葡萄汁!");
        }
    }

    // 西瓜汁
    public class WatermelonDrink extends Drink {
        @Override
        public void desc() {
            System.out.println("這是一杯西瓜汁!");
        }
    }

    // 飲料工廠
    public class DrinkFactory {
        // name:飲料名字
        public Drink getDrink(String name){
            if("apple".equals(name)){
                return new AppleDrink();
            }else if("watermelon".equals(name)){
                return new WatermelonDrink();
            }else if("grape".equals(name)){
                return new GrapeDrink();
            }
            return null;
        }
    }

    // 客戶端
    public class Client {
        public static void main(String[] args) {
            DrinkFactory drinkFactory = new DrinkFactory();
            // 顧客想要蘋果汁
            Drink appleDrink = drinkFactory.getDrink("apple");
            appleDrink.desc();

            // 顧客想要葡萄汁
            Drink grapeDrink = drinkFactory.getDrink("grape");
            grapeDrink.desc();
        }
    }
    2、簡單工廠的適用場景

    (1)、工廠類負責創(chuàng)建的對象比較少。
    (2)、客戶端(應用層)只知道傳入工廠類的參數(shù),對于如何創(chuàng)建對象(邏輯)不關心。

    3、簡單工廠的優(yōu)點

    只需要傳入一個正確的參數(shù),就可以獲取你所需要的對象,而無需知道其創(chuàng)建細節(jié),工廠類要有必要的判斷邏輯(if else),可以決定在什么時候創(chuàng)建哪一個產(chǎn)品的實例,客戶端可以免除直接創(chuàng)建對象的責任。

    4、簡單工廠的缺點

    (1)、工廠類的職責相對較重,增加新的產(chǎn)品,需要修改工廠類的判斷邏輯(增加if else分支),修改就意味著引入風險,這違反了開閉原則。
    (2)、當產(chǎn)品很多的時候,這個工廠類就會很復雜,不利于維護和擴展,代碼無法閱讀,很難交接。
    (3)、無法形成基于繼承的等級結(jié)構(gòu)。在工廠方法和抽象工廠中,會講到產(chǎn)品族和產(chǎn)品等級結(jié)構(gòu),再了解什么是基于繼承的等級結(jié)構(gòu)。

    三、工廠方法

    1、工廠方法示例

    后來店里飲料品種越來越多,每增加一款飲料都需要讓服務員知曉,否則顧客說的時候,服務員就無法提供(這就是簡單工廠中所說的對工廠類的修改)。

    于是,小明直接買了飲料機,每種飲料都有自己的飲料機(這個飲料機就是工廠方法中的產(chǎn)品工廠,每個產(chǎn)品都有自己的工廠),顧客想喝什么,就自己去飲料機取,飲品店以后想增加飲料,只要增加飲料機即可(工廠方法相對于簡單工廠,更加易于擴展)。

    // 抽象飲料
    public abstract class Drink {
        public abstract void desc();
    }

    // 蘋果汁
    public class AppleDrink extends Drink {
        @Override
        public void desc() {
            System.out.println("這是一杯蘋果汁!");
        }
    }

    // 葡萄汁
    public class GrapeDrink extends Drink {
        @Override
        public void desc() {
            System.out.println("這是一杯葡萄汁!");
        }
    }

    // 西瓜汁
    public class WatermelonDrink extends Drink {
        @Override
        public void desc() {
            System.out.println("這是一杯西瓜汁!");
        }
    }

    // 抽象飲料工廠
    public abstract class DrinkFactory {
        public abstract Drink getDrink();
    }

    // 蘋果汁飲料工廠(蘋果汁飲料機)
    public class AppleDrinkFactory extends DrinkFactory {
        @Override
        public Drink getDrink() {
            return new AppleDrink();
        }
    }

    // 葡萄汁飲料工廠
    public class GrapeDrinkFactory extends DrinkFactory {
        @Override
        public Drink getDrink() {
            return new GrapeDrink();
        }
    }

    // 西瓜汁飲料工廠
    public class WatermelonDrinkFactory extends DrinkFactory {
        @Override
        public Drink getDrink() {
            return new WatermelonDrink();
        }
    }

    // 客戶端
    public class Client {
        public static void main(String[] args) {
            // 顧客想要蘋果汁
            DrinkFactory appleDrinkFactory = new AppleDrinkFactory();
            Drink appleDrink = appDrinkFactory.getDrink();
            appleDrink.desc();

            // 顧客想要葡萄汁
            DrinkFactory grapeDrinkFactory = new GrapeDrinkFactory();
            Drink grapeDrink = grapeDrinkFactory.getDrink();
            grapeDrink.desc();
        }
    }
    2、工廠方法和簡單工廠的區(qū)別

    簡單工廠:所有的產(chǎn)品都在一個工廠中生產(chǎn),在工廠中使用if else根據(jù)傳入?yún)?shù)判斷生產(chǎn)哪種產(chǎn)品,當增加一種產(chǎn)品的時候,就需要修改工廠的if else邏輯。

    工廠方法:每種產(chǎn)品都有自己的工廠,當需要增加一種產(chǎn)品時,無需修改現(xiàn)有的工廠,只需要增加一種工廠即可。遵循了開閉原則,對于擴展是開放的,對于修改是關閉的。

    3、工廠方法的優(yōu)點

    (1)、用戶只需要關心所需產(chǎn)品對應的工廠,無需關心產(chǎn)品的創(chuàng)建細節(jié)。
    (2)、加入新產(chǎn)品時,只需要再增加對應的工廠,而不用修改已有的工廠,符合開閉原則,提高擴展性。

    4、工廠方法的缺點

    類爆炸,因為每個產(chǎn)品都要有一個工廠,如果產(chǎn)品很多,那就會有很多的工廠。用上面的例子來描述,如果后續(xù)飲品店出了成百上千種飲品,就要在店里放成百上千臺飲料機,店里放不下啊。。。

    四、抽象工廠

    1、抽象工廠示例

    至于抽象工廠模式,可以用套餐來理解。小明在后期,除了提供飲品,還給每種飲品搭配了合適的甜點,向顧客提供下午茶套餐,以此來提高銷售量。

    所以飲品店制定了一套標準(抽象工廠,具體工廠需要遵循的工廠接口),所有的套餐(具體工廠)必須遵循該標準,比如這個抽象標準可能是:1、需要有一杯果汁。2、需要有一塊甜點。于是有了第一個套餐(具體工廠):西瓜汁 + 泡芙,我們稱之為套餐A,那顧客點套餐A,即可獲得剛才所說產(chǎn)品。當然這里面的西瓜汁、泡芙(具體產(chǎn)品對象),也需要遵守相應的產(chǎn)品規(guī)則(產(chǎn)品接口),以保證顧客能吃到放心食品。

    產(chǎn)品接口如下:

    // 飲料抽象類
    public abstract class Drink {
        public abstract void desc();
    }

    // 甜點抽象類
    public abstract class Dessert {
        public abstract void desc();
    }

    具體產(chǎn)品對象如下:

    // 蘋果汁
    public class AppleDrink extends Drink {
        @Override
        public void desc() {
            System.out.println("這是一杯蘋果汁!");
        }
    }

    // 葡萄汁
    public class GrapeDrink extends Drink {
        @Override
        public void desc() {
            System.out.println("這是一杯葡萄汁!");
        }
    }

    // 西瓜汁
    public class WatermelonDrink extends Drink {
        @Override
        public void desc() {
            System.out.println("這是一杯西瓜汁!");
        }
    }

    // 泡芙
    public class Puff extends Dessert {
        @Override
        public void desc() {
            System.out.println("這是一塊泡芙!");
        }
    }

    // 慕斯蛋糕
    public class MousseCake extends Dessert {
        @Override
        public void desc() {
            System.out.println("這是一塊慕斯蛋糕!");
        }
    }

    // 提拉米蘇蛋糕
    public class Tiramisu extends Dessert {
        @Override
        public void desc() {
            System.out.println("這是一塊提拉米蘇蛋糕!");
        }
    }

    抽象工廠如下:

    // 下午茶套餐工廠
    public interface SetFactory {
        Drink getDrink();
        Dessert getDessert();
    }

    具體工廠如下:

    /**
     * 套餐A的工廠
     * 套餐A提供西瓜汁 + 泡芙
     */

    public class ASetFactory implements SetFactory {
        @Override
        public Drink getDrink() {
            return new WatermelonDrink();
        }

        @Override
        public Dessert getDessert() {
            return new Puff();
        }
    }

    /**
     * 套餐B的工廠
     * 套餐B提供葡萄汁 + 慕斯蛋糕
     */

    public class BSetFactory implements SetFactory {

        @Override
        public Drink getDrink() {
            return new GrapeDrink();
        }

        @Override
        public Dessert getDessert() {
            return new MousseCake();
        }
    }

    /**
     * 套餐C的工廠
     * 套餐C提供蘋果汁 + 提拉米蘇蛋糕
     */

    public class CSetFactory implements SetFactory {
        @Override
        public Drink getDrink() {
            return new AppleDrink();
        }

        @Override
        public Dessert getDessert() {
            return new Tiramisu();
        }
    }

    客戶端如下:

    public class Client {
        public static void main(String[] args) {
            // 顧客想要一份A套餐
            System.out.println("------A套餐-------");
            SetFactory aSetFactory = new ASetFactory();
            Drink aDrink = aSetFactory.getDrink();
            Dessert aDessert = aSetFactory.getDessert();
            aDrink.desc();
            aDessert.desc();

            // 顧客想要一份B套餐
            System.out.println("------B套餐-------");
            SetFactory bSetFactory = new BSetFactory();
            Drink bDrink = bSetFactory.getDrink();
            Dessert bDessert = bSetFactory.getDessert();
            bDrink.desc();
            bDessert.desc();
        }
    }

    在這里我們看到,對于抽象工廠是無需指定具體的果汁和甜點,但是這些果汁、甜點卻是相互依賴的,這也是抽象工廠的意圖:提供一個創(chuàng)建一系列相關或相互依賴對象的接口,而無需指定它們具體的類。

    3、抽象工廠的優(yōu)點

    將一系列的產(chǎn)品統(tǒng)一到一起創(chuàng)建。

    4、抽象工廠的缺點

    (1)、規(guī)定了所有可能被創(chuàng)建的產(chǎn)品集合,當產(chǎn)品集合中需要擴展新的產(chǎn)品時,需要修改抽象工廠的接口,違反了開閉原則,比如上面的例子,當我們需要在套餐中加入一份小吃時,就需要修改抽象工廠和所有的具體工廠,改動很大。
    (2)、增加了系統(tǒng)的抽象性和理解難度。

    5、適用場景

    強調(diào)一系列相關的產(chǎn)品組成一個產(chǎn)品集合一起使用時,此時使用抽象工廠模式。

    五:工廠模式總結(jié)

    我們結(jié)合上面飲品店的例子,來總結(jié)一下簡單工廠、工廠方法、抽象工廠這三種工廠有什么不同吧,方便大家更好地記憶。

    簡單工廠,就是所有的產(chǎn)品都在這個工廠中生產(chǎn),用戶需要告訴工廠他需要哪個產(chǎn)品,工廠才能給他對應的產(chǎn)品。

    簡單工廠

    工廠方法,就是每種產(chǎn)品都有自己的工廠,用戶想要哪個產(chǎn)品,直接去對應的工廠取即可。

    工廠方法

    抽象工廠,相當于對所有的產(chǎn)品進行分類(分類的維度根據(jù)業(yè)務場景來決定),同一種類的產(chǎn)品在同一工廠生產(chǎn),用戶想要哪一種類的產(chǎn)品,直接去對應的工廠取即可。

    抽象工廠

    標注:圖中綠色方框表示工廠,橘色方框表示產(chǎn)品。


    瀏覽 42
    點贊
    評論
    收藏
    分享

    手機掃一掃分享

    分享
    舉報
    評論
    圖片
    表情
    推薦
    點贊
    評論
    收藏
    分享

    手機掃一掃分享

    分享
    舉報

    <kbd id="5sdj3"></kbd>
    <th id="5sdj3"></th>

  • <dd id="5sdj3"><form id="5sdj3"></form></dd>
    <td id="5sdj3"><form id="5sdj3"><big id="5sdj3"></big></form></td><del id="5sdj3"></del>

  • <dd id="5sdj3"></dd>
    <dfn id="5sdj3"></dfn>
  • <th id="5sdj3"></th>
    <tfoot id="5sdj3"><menuitem id="5sdj3"></menuitem></tfoot>

  • <td id="5sdj3"><form id="5sdj3"><menu id="5sdj3"></menu></form></td>
  • <kbd id="5sdj3"><form id="5sdj3"></form></kbd>
    台湾娱乐成人网综合网 | 成人黄色电影在线视频 | 天天干天天日一本着 | 91美女被艹 | 婷婷天堂网 |