02.工廠模式設計思想

潇湘剑雨yc發表於2024-10-17

02.工廠模式設計思想

目錄介紹

  • 01.工廠模式設計
    • 1.1 工廠模式型別
    • 1.2 工廠模式思考
    • 1.3 思考一個題目
  • 02.簡單工廠介紹
    • 2.1 簡單工廠背景
    • 2.2 簡單工廠定義
    • 2.3 簡單工廠結構
    • 2.4 簡單工廠案例
    • 2.5 簡單工廠分析
    • 2.6 簡單工廠場景
    • 2.7 簡單工廠不足
  • 03.工廠方法介紹
    • 3.1 工廠方法背景
    • 3.2 工廠方法定義
    • 3.3 工廠方法結構
    • 3.4 工廠方法案例
    • 3.5 工廠方法分析
    • 3.6 工廠方法場景
    • 3.7 工廠方法不足
  • 04.抽象工廠介紹
    • 4.1 抽象工廠背景
    • 4.2 抽象工廠定義
    • 4.3 抽象工廠結構
    • 4.4 抽象工廠案例
    • 4.5 抽象工廠分析
    • 4.6 抽象工廠場景
    • 4.7 抽象工廠不足
  • 05.工廠模式總結
    • 5.1 工廠設計總結
    • 5.2 如何選擇
    • 5.3 更多內容推薦

01.工廠模式設計

1.0 本部落格AI摘要

本文件詳細介紹了工廠模式設計思想,包括簡單工廠、工廠方法和抽象工廠三種型別。簡單工廠透過引數返回不同類的例項,適合物件較少的場景;工廠方法透過定義抽象工廠介面,由子類實現具體物件的建立,增強擴充套件性;抽象工廠則能建立多個產品族,適用於產品間有依賴關係的情況。文件還透過咖啡店點餐系統案例,展示了三種模式的應用及優缺點,幫助讀者理解和選擇合適的工廠模式。

1.1 工廠模式型別

一般情況下,工廠模式分為三種更加細分的型別:簡單工廠、工廠方法和抽象工廠。

不過,在 GoF 的《設計模式》一書中,它將簡單工廠模式看作是工廠方法模式的一種特例,所以工廠模式只被分成了工廠方法和抽象工廠兩類。

實際上, 在這三種細分的工廠模式中,簡單工廠、工廠方法原理比較簡單,在實際的專案中也比較常用。而抽象工廠的原理稍微複雜點,在實際的專案中相對也不常用。

1.2 工廠模式思考

講解的重點也不是原理和實現,因為這些都很簡單,重點還是帶你搞清楚應用場景。什麼時候該用工廠模式?相對於直接 new 來建立物件,用工廠模式來建立究竟有什麼好處呢?

1.3 思考一個題目

你現在是一個做咖啡的老闆。你要在店裡買各種咖啡,而這些咖啡中有的加冰,有的加奶,有的加糖。比如美式咖啡,拿鐵咖啡,摩卡咖啡,巴西咖啡等等!你需要設計一個咖啡店點餐系統!

簡單工廠實現:設計一個咖啡類(Coffee),並定義其兩個子類(美式咖啡AmericanCoffee和拿鐵咖啡LatteCoffee);再設計一個咖啡店類(CoffeeStore),咖啡店具有點咖啡的功能。

  1. 創造抽象產品角色,比如總結出很多咖啡都可能會,加糖,加冰,加奶,因此把它抽成抽象方法。
  2. 具體產品角色,這塊有:美式咖啡類,拿鐵咖啡類,摩卡咖啡等,這些都是具體的咖啡產品。
  3. 工廠角色。負責建立不同咖啡,為了簡便高效地分配咖啡,設了根據型別(比如americanlatte)來提供不同的咖啡。

新增需求1: 後期我想要再增加一個或者多個新的咖啡,簡單工廠這個案例則需要修改工廠角色,這個違背了開閉原則。那有什麼好的方式解決呢?可以用工廠方法模式。

工廠方法實現

  1. Product:抽象產品。這個和簡單工廠模式程式碼一樣,忽略!
  2. ConcreteProduct:具體產品。這個和簡單工廠模式程式碼一樣,忽略!
  3. Factory:抽象工廠。這塊定義咖啡工廠介面,透過該介面子類可以自己實現咖啡建立。
  4. ConcreteFactory:具體工廠。這裡主要是建立美式咖啡工廠類,建立拿鐵咖啡工廠類。

新增需求2: 後期咖啡點業務增多,現在不僅生產咖啡,還要生產甜點,請用抽象工廠去實現咖啡店咖啡和甜點的生產。這個可以用到抽象工廠模式。

抽象工廠實現

  1. AbstractFactory:抽象工廠。這個時候則需要抽象出生產甜品,生產咖啡的介面。
  2. ConcreteFactory:具體工廠。分別實現生產甜品的具體工廠,生產咖啡的具體工廠。
  3. AbstractProduct:抽象產品。這裡把甜點抽象成一個產品,把咖啡抽象成一個產品。
  4. Product:具體產品。建立具體的美式咖啡,拿鐵咖啡產品。建立具體的提拉米蘇甜點,抹茶慕斯甜點。

02.簡單工廠介紹

2.1 簡單工廠背景

考慮一個簡單的軟體應用場景,一個軟體系統可以提供多個外觀不同的按鈕(如圓形按鈕、矩形按鈕、菱形按鈕等),這些按鈕都源自同一個基類,不過在繼承基類後不同的子類修改了部分屬性從而使得它們可以呈現不同的外觀。

如果我們希望在使用這些按鈕時,不需要知道這些具體按鈕類的名字,只需要知道表示該按鈕類的一個引數,並提供一個呼叫方便的方法,把該引數傳入方法即可返回一個相應的按鈕物件,此時,就可以使用簡單工廠模式。

2.2 簡單工廠定義

簡單工廠模式(Simple Factory Pattern):又稱為靜態工廠方法(Static Factory Method)模式,它屬於類建立型模式。在簡單工廠模式中,可以根據引數的不同返回不同類的例項。簡單工廠模式專門定義一個類來負責建立其他類的例項,被建立的例項通常都具有共同的父類。

2.3 簡單工廠結構

簡單工廠模式包含如下角色:

  1. Factory:工廠角色 。工廠角色負責實現建立所有例項的內部邏輯
  2. Product:抽象產品角色 。抽象產品角色是所建立的所有物件的父類,負責描述所有例項所共有的公共介面
  3. ConcreteProduct:具體產品角色 。具體產品角色是建立目標,所有建立的物件都充當這個角色的某個具體類的例項。

2.4 簡單工廠案例

創造抽象產品角色,比如總結出很多咖啡都可能會,加糖,加冰,加奶,因此把它抽成抽象方法。

// 咖啡類(父類)--抽象類
public abstract class Coffee {

    //每個咖啡都有名字,所以抽取到父類,定義為抽象方法
    public abstract String getName();

    public void addMilk() {
        System.out.println("加奶...");
    }

    public void addSugar() {
        System.out.println("加糖...");
    }
}

具體產品角色,這塊有:美式咖啡類,拿鐵咖啡類,摩卡咖啡等,這些都是具體的咖啡產品。

// 美式咖啡類 繼承 咖啡類
public class AmericanCoffee extends Coffee {
    @Override
    public String getName() {
        return "美式咖啡";
    }

    public void show() {
        System.out.println("我是美式咖啡....");
    }
}

// 拿鐵咖啡類 繼承 咖啡類
public class LatteCoffee extends Coffee {
    @Override
    public String getName() {
        return "拿鐵咖啡";
    }
}

工廠角色。負責建立不同咖啡,為了簡便高效地分配咖啡,設了根據型別(比如americanlatte)來提供不同的咖啡。

// 咖啡工廠
public class SimpleFactory {
    //提供方法,建立具體咖啡
    public Coffee createCoffee(String type) {
        Coffee coffee = null;
        if ("american".equals(type)) {
            coffee = new AmericanCoffee(); //多型
        } else if ("latte".equals(type)) {
            coffee = new LatteCoffee(); //多型
        } else {
            throw new RuntimeException("沒有這種咖啡!");
        }

        return coffee;
    }
}

儘管簡單工廠模式的程式碼實現中,有多處 if 分支判斷邏輯,違背開閉原則,但權衡擴充套件性和可讀性,這樣的程式碼實現在大多數情況下(比如,不需要頻繁地新增不同型別咖啡)是沒有問題的。

最後就是咖啡點透過不同型別建立不同的咖啡

private void test() {
    // 建立咖啡店物件,進行點咖啡
    CoffeeStore store = new CoffeeStore();
    //隱含了多型,在工廠裡
    Coffee coffee = store.orderCoffee("american");
    String name = coffee.getName();
    System.out.println(name);
    //加糖...
    //加奶...
    //美式咖啡
}

// 咖啡店類
public class CoffeeStore {
    public Coffee orderCoffee(String type) {
        //此處解除了咖啡店類和具體的咖啡類的依賴,降低了耦合
        // 建立工廠物件目的是建立具體的咖啡
        SimpleFactory sf = new SimpleFactory();
        // 建立咖啡,返回具體的咖啡物件
        Coffee coffee = sf.createCoffee(type);
        coffee.addSugar();
        coffee.addMilk();
        // 將具體的咖啡物件返回
        return coffee;
    }
}

思考一下這種場景,假如我們要更換物件(即,新增一個新的咖啡品種),我們勢必要需求修改SimpleCoffeeFactory的程式碼,違反了開閉原則。

2.5 簡單工廠分析

將物件的建立和物件本身業務處理分離可以降低系統的耦合度,使得兩者修改起來都相對容易。

簡單工廠模式的要點在於:當你需要什麼,只需要傳入一個正確的引數,就可以獲取你所需要的物件,而無須知道其建立細節。

簡單工廠模式最大的問題在於工廠類的職責相對過重,增加新的產品需要修改工廠類的判斷邏輯,這一點與開閉原則是相違背的。

2.6 簡單工廠場景

在以下情況下可以使用簡單工廠模式:

  1. 工廠類負責建立的物件比較少:由於建立的物件較少,不會造成工廠方法中的業務邏輯太過複雜。
  2. 客戶端只知道傳入工廠類的引數,對於如何建立物件不關心:客戶端既不需要關心建立細節,甚至連類名都不需要記住,只需要知道型別所對應的引數。

模式應用場景

  1. JDK類庫中廣泛使用了簡單工廠模式,如工具類java.text.DateFormat,它用於格式化一個本地日期或者時間。
  2. Java加密技術,獲取不同加密演算法的金鑰生成器: KeyGenerator keyGen=KeyGenerator.getInstance("DESede");

2.7 簡單工廠不足

缺點1: 使用簡單工廠模式將會增加系統中類的個數,在一定程式上增加了系統的複雜度和理解難度。舉個例子……

缺點2: 系統擴充套件困難,一旦新增新產品就不得不修改工廠邏輯,在產品型別較多時,有可能造成工廠邏輯過於複雜,不利於系統的擴充套件和維護。舉個例子……

缺點3: 由於工廠類集中了所有產品建立邏輯,一旦不能正常工作,整個系統都要受到影響。違反了高內聚的責任分配原則。

缺點4: 簡單工廠模式中的if else判斷非常多,完全是Hard Code,如果有一個新產品要加進來,就要同時新增一個新產品類,並且必須修改工廠類,再加入一個 else if 分支才可以, 這樣就違背了 “開放-關閉原則”中的對修改關閉的準則了。當系統中的具體產品類不斷增多時候,就要不斷的修改工廠類,對系統的維護和擴充套件不利。

03.工廠方法介紹

3.1 工廠方法背景

現在對該系統進行修改,不再設計一個按鈕工廠類來統一負責所有產品的建立,而是將具體按鈕的建立過程交給專門的工廠子類去完成,我們先定義一個抽象的按鈕工廠類,再定義具體的工廠類來生成圓形按鈕、矩形按鈕、菱形按鈕等,它們實現在抽象按鈕工廠類中定義的方法。

這種抽象化的結果使這種結構可以在不修改具體工廠類的情況下引進新的產品,如果出現新的按鈕型別,只需要為這種新型別的按鈕建立一個具體的工廠類就可以獲得該新按鈕的例項,這一特點無疑使得工廠方法模式具有超越簡單工廠模式的優越性,更加符合“開閉原則”。

3.2 工廠方法定義

工廠方法模式(Factory Method Pattern)又稱為工廠模式,也叫虛擬構造器(Virtual Constructor)模式或者多型工廠(Polymorphic Factory)模式,它屬於類建立型模式。

在工廠方法模式中,工廠父類負責定義建立產品物件的公共介面,而工廠子類則負責生成具體的產品物件,這樣做的目的是將產品類的例項化操作延遲到工廠子類中完成,即透過工廠子類來確定究竟應該例項化哪一個具體產品類。

3.3 工廠方法結構

工廠方法模式包含如下角色:

  1. Product:抽象產品。定義了產品的規範,描述了產品的主要特性和功能。
  2. ConcreteProduct:具體產品。實現了抽象產品角色所定義的介面,由具體工廠來建立,它同具體工廠之間一一對應。
  3. Factory:抽象工廠。提供了建立產品的介面,呼叫者透過抽象工廠訪問具體工廠(多型)的工廠方法來建立產品物件。
  4. ConcreteFactory:具體工廠。主要是實現抽象工廠中的抽象方法,完成具體產品的建立。

3.4 工廠方法案例

建立抽象產品。這裡抽象出咖啡的公共特性,比如總結出很多咖啡都可能會,加糖,加冰,加奶,因此把它抽成抽象方法。這個和簡單工廠模式程式碼一樣,忽略!

建立具體產品。這塊有:美式咖啡類,拿鐵咖啡類,摩卡咖啡等,這些都是具體的咖啡產品。這個和簡單工廠模式程式碼一樣,忽略!

建立抽象介面工廠。定義咖啡工廠介面,透過該介面子類可以自己實現咖啡建立。

// 定義咖啡工廠介面
public interface CoffeeFactory {
    public abstract Coffee creatCoffee();
}

建立具體工廠。這裡主要是建立美式咖啡工廠類,建立拿鐵咖啡工廠類

// 建立拿鐵咖啡工廠類 實現 咖啡工廠類介面
public class LatteCoffeeFactory implements CoffeeFactory{
    @Override
    public Coffee creatCoffee() {
        return new LatteCoffee();
    }
}

// 建立美式咖啡工廠類 實現 咖啡工廠類介面
public class AmericanCoffeeFactory implements CoffeeFactory {
    @Override
    public Coffee creatCoffee() {
        return new AmericanCoffee();
    }
}

最後就是咖啡點透過不同型別建立不同的咖啡。這個時候看看程式碼如下所示:

private void test() {
    // 建立咖啡店類物件
    CoffeeStore coffeeStore = new CoffeeStore();
    //建立拿鐵咖啡工廠,多型
    CoffeeFactory coffeeFactory = new LatteCoffeeFactory();
    //CoffeeFactory amerFactory  = new AmericanCoffeeFactory();
    coffeeStore.setCoffeeFactory(coffeeFactory);
    // 點咖啡
    Coffee coffee = coffeeStore.orderCoffee();
    System.out.println(coffee.getName());
}


//咖啡店類
public class CoffeeStore {

    private CoffeeFactory coffeeFactory;

    public void setCoffeeFactory(CoffeeFactory coffeeFactory) {
        this.coffeeFactory = coffeeFactory;
    }

    public Coffee orderCoffee(){
        // 咖啡工廠來建立具體的咖啡
        Coffee coffee = coffeeFactory.creatCoffee();
        // 加配料
        coffee.addMilk();
        coffee.addSugar();
        return coffee;
    }
}

3.5 工廠方法分析

工廠方法模式是簡單工廠模式的進一步抽象和推廣。由於使用了物件導向的多型性,工廠方法模式保持了簡單工廠模式的優點,而且克服了它的缺點。

在工廠方法模式中,核心的工廠類不再負責所有產品的建立,而是將具體建立工作交給子類去做。這個核心類僅僅負責給出具體工廠必須實現的介面,而不負責哪一個產品類被例項化這種細節,這使得工廠方法模式可以允許系統在不修改工廠角色的情況下引進新產品。

在工廠方法模式中,工廠方法用來建立客戶所需要的產品,同時還向客戶隱藏了哪種具體產品類將被例項化這一細節,使用者只需要關心所需產品對應的工廠,無須關心建立細節,甚至無須知道具體產品類的類名。

使用工廠方法模式的另一個優點是在系統中加入新產品時,無須修改抽象工廠和抽象產品提供的介面,無須修改客戶端,也無須修改其他的具體工廠和具體產品,而只要新增一個具體工廠和具體產品就可以了。這樣,系統的可擴充套件性也就變得非常好,完全符合“開閉原則”。

3.6 工廠方法場景

在以下情況下可以使用工廠方法模式:

  1. 一個類不知道它所需要的物件的類:在工廠方法模式中,客戶端不需要知道具體產品類的類名,只需要知道所對應的工廠即可,具體的產品物件由具體工廠類建立;客戶端需要知道建立具體產品的工廠類。
  2. 一個類透過其子類來指定建立哪個物件:在工廠方法模式中,對於抽象工廠類只需要提供一個建立產品的介面,而由其子類來確定具體要建立的物件,利用物件導向的多型性和里氏代換原則,在程式執行時,子類物件將覆蓋父類物件,從而使得系統更容易擴充套件。
  3. 將建立物件的任務委託給多個工廠子類中的某一個,客戶端在使用時可以無須關心是哪一個工廠子類建立產品子類,需要時再動態指定,可將具體工廠類的類名儲存在配置檔案或資料庫中。

3.7 工廠方法不足

在新增新產品時,需要編寫新的具體產品類,而且還要提供與之對應的具體工廠類,系統中類的個數將成對增加,在一定程度上增加了系統的複雜度,有更多的類需要編譯和執行,會給系統帶來一些額外的開銷。

由於考慮到系統的可擴充套件性,需要引入抽象層,在客戶端程式碼中均使用抽象層進行定義,增加了系統的抽象性和理解難度,且在實現時可能需要用到DOM、反射等技術,增加了系統的實現難度。

04.抽象工廠介紹

4.1 抽象工廠背景

在工廠方法模式中具體工廠負責生產具體的產品,每一個具體工廠對應一種具體產品,工廠方法也具有唯一性,一般情況下,一個具體工廠中只有一個工廠方法或者一組過載的工廠方法。但是有時候我們需要一個工廠可以提供多個產品物件,而不是單一的產品物件。

當系統所提供的工廠所需生產的具體產品並不是一個簡單的物件,而是多個位於不同產品等級結構中屬於不同型別的具體產品時需要使用抽象工廠模式。

抽象工廠模式與工廠方法模式最大的區別在於,工廠方法模式針對的是一個產品等級結構,而抽象工廠模式則需要面對多個產品等級結構,一個工廠等級結構可以負責多個不同產品等級結構中的產品物件的建立。

4.2 抽象工廠定義

抽象工廠模式(Abstract Factory Pattern):提供一個建立一系列相關或相互依賴物件的介面,而無須指定它們具體的類。抽象工廠模式又稱為Kit模式,屬於物件建立型模式。

4.3 抽象工廠結構

抽象工廠模式包含如下角色:

  1. AbstractFactory:抽象工廠。提供了建立產品的介面,它包含多個建立產品的方法,可以建立多個不同等級的產品。
  2. ConcreteFactory:具體工廠。主要是實現抽象工廠中的多個抽象方法,完成具體產品的建立。
  3. AbstractProduct:抽象產品。定義了產品的規範,描述了產品的主要特性和功能,抽象工廠模式有多個抽象產品。
  4. Product:具體產品。實現了抽象產品角色所定義的介面,由具體工廠來建立,它 同具體工廠之間是多對一的關係。

4.4 抽象工廠案例

後期咖啡點業務增多,現在不僅生產咖啡,還要生產甜點,請用抽象工廠去實現咖啡店咖啡和甜點的生產。

實現咖啡抽象產品和具體產品,程式碼如下:

// 咖啡抽象類
public abstract class Coffee {
    public abstract String getName();

    public void addMilk(){
        System.out.println("加奶...");
    }
    public void addSugar(){
        System.out.println("加糖...");
    }
}

// 美式咖啡類 繼承 咖啡類
public class AmericanCoffee extends Coffee {
    @Override
    public String getName() {
        return "美式咖啡";
    }

    public void show() {
        System.out.println("我是美式咖啡....");
    }
}

// 拿鐵咖啡類 繼承 咖啡類
public class LatteCoffee extends Coffee {
    @Override
    public String getName() {
        return "拿鐵咖啡";
    }
}

實現甜品抽象產品和具體產品,程式碼如下:

// 抽象甜品類
public abstract class Dessert {
    // 定義展示具體甜品的規範
    public abstract void show();
}
// 具體甜品--提拉米蘇類 繼承 抽象甜品類
public class Tiramisu extends Dessert{
    @Override
    public void show() {
        System.out.println("提拉米蘇...");
    }
}
// 具體甜品--抹茶慕斯類  繼承 抽象甜品類
public class MatchaMousse extends Dessert {
    @Override
    public void show() {
        System.out.println("抹茶慕斯...");
    }
}

抽象工廠,這個時候則需要抽象出生產甜品,生產咖啡的介面。程式碼如下所示

//抽象工廠  生產咖啡類  生產甜品類
public interface DessertFactory {

    // 生產咖啡
    Coffee createCoffee();

    // 生產甜品
    Dessert createDessert();
}

具體工廠,分別實現生產甜品的具體工廠,生產咖啡的具體工廠。程式碼如下所示

// 義大利風味甜品工廠
// 生產拿鐵咖啡和提拉米蘇甜品
public class ItalyDessertFactory implements DessertFactory{
    // 生產拿鐵咖啡
    @Override
    public Coffee createCoffee() {
        return new LatteCoffee();
    }
    // 生產提拉米蘇
    @Override
    public Dessert createDessert() {
        return new Tiramisu();
    }
}

// 美式風味的甜品工廠
// 生美式咖啡 和 抹茶慕斯
public class AmericanDessertFactory implements DessertFactory{
    // 生產美式咖啡
    @Override
    public Coffee createCoffee() {
        return new AmericanCoffee();
    }

    // 生產抹茶慕斯
    @Override
    public Dessert createDessert() {
        return new MatchaMousse();
    }
}

最後就是咖啡點透過不同型別建立不同的咖啡,也可以點不同型別的甜品。這個時候看看程式碼如下所示:

private void test() {
    // 建立義大利風味甜品工廠物件
    // 該工廠生產拿鐵咖啡 和提拉米蘇
    ItalyDessertFactory factory = new ItalyDessertFactory();
    // 獲取拿鐵咖啡
    Coffee coffee = factory.createCoffee();
    System.out.println(coffee.getName());//拿鐵咖啡
    // 獲取提拉米蘇
    Dessert dessert = factory.createDessert();
    dessert.show();//提拉米蘇...

    
    // 建立美式風味的甜品工廠物件
    //該工廠生產美式咖啡 和抹茶慕斯
    AmericanDessertFactory factory1 = new AmericanDessertFactory();
    // 獲取美式咖啡
    Coffee coffee1 = factory1.createCoffee();
    System.out.println(coffee1.getName());//美式咖啡
    // 獲取抹茶慕斯
    Dessert dessert1 = factory1.createDessert();
    dessert1.show();//抹茶慕斯...
}

思考一下該案例

  1. 當一個產品族中的多個物件被設計成一起工作時,它能保證客戶端始終只使用同一個產品族中的物件。
  2. 當產品族中需要增加一個新的產品時,所有的工廠類都需要進行修改。

4.5 抽象工廠分析

當一個產品族中的多個物件被設計成一起工作時,它能夠保證客戶端始終只使用同一個產品族中的物件。這對一些需要根據當前環境來決定其行為的軟體系統來說,是一種非常實用的設計模式。

增加新的具體工廠和產品族很方便,無須修改已有系統,符合“開閉原則”。

4.6 抽象工廠場景

在以下情況下可以使用抽象工廠模式:

  1. 一個系統不應當依賴於產品類例項如何被建立、組合和表達的細節,這對於所有型別的工廠模式都是重要的。
  2. 系統中有多於一個的產品族,而每次只使用其中某一產品族。
  3. 屬於同一個產品族的產品將在一起使用,這一約束必須在系統的設計中體現出來。
  4. 系統提供一個產品類的庫,所有的產品以同樣的介面出現,從而使客戶端不依賴於具體實現。

4.7 抽象工廠不足

在新增新的產品物件時,難以擴充套件抽象工廠來生產新種類的產品,這是因為在抽象工廠角色中規定了所有可能被建立的產品集合,要支援新種類的產品就意味著要對該介面進行擴充套件,而這將涉及到對抽象工廠角色及其所有子類的修改,顯然會帶來較大的不便。

開閉原則的傾斜性(增加新的工廠和產品族容易,增加新的產品等級結構麻煩)。

05.工廠模式總結

5.1 工廠設計總結

01.工廠模式設計

工廠模式分類,大概分為三種更加細分的型別:簡單工廠、工廠方法和抽象工廠。一般情況下,使用簡單工廠,工廠方法場景稍多。

工廠模式思考,主要要搞清楚應用場景。什麼時候該用工廠模式?相對於直接 new 來建立物件,用工廠模式來建立究竟有什麼好處呢?

思考一個題目,你要在店裡買各種咖啡,而這些咖啡中有的加冰,有的加奶,有的加糖。比如美式咖啡,拿鐵咖啡,摩卡咖啡,巴西咖啡等等!用簡單工廠,工廠方法,抽象工廠分別實現。

02.簡單工廠介紹

一句話概括簡單工廠:可以根據引數的不同返回不同類的例項。

簡單工廠模式包含如下角色:抽象產品角色,具體產品角色,工廠角色。

簡單工廠實現:

  1. 創造抽象產品角色,比如總結出很多咖啡都可能會,加糖,加冰,加奶,因此把它抽成抽象方法。
  2. 具體產品角色,這塊有:美式咖啡類,拿鐵咖啡類,摩卡咖啡等,這些都是具體的咖啡產品。
  3. 工廠角色。負責建立不同咖啡,為了簡便高效地分配咖啡,設了根據型別(比如americanlatte)來提供不同的咖啡。

03.工廠方法介紹

工廠方法模式:定義一個建立物件的介面(指的是抽象工廠),讓子類(具體工廠)決定例項化哪個產品類物件。工廠方法使一個產品類的例項化延遲到其工廠的子類。

工廠方法實現:

  1. Product:抽象產品。這個和簡單工廠模式程式碼一樣,忽略!
  2. ConcreteProduct:具體產品。這個和簡單工廠模式程式碼一樣,忽略!
  3. Factory:抽象工廠。這塊定義咖啡工廠介面,透過該介面子類可以自己實現咖啡建立。
  4. ConcreteFactory:具體工廠。這裡主要是建立美式咖啡工廠類,建立拿鐵咖啡工廠類。

04.抽象工廠介紹

抽象工廠模式:抽象工廠模式是工廠方法模式的升級版本,工廠方法模式只生產一個等級(即,同種的產品)的產品,而抽象工廠模式可生產多個等級(即,多種產品)的產品。

抽象工廠實現:

  1. AbstractFactory:抽象工廠。這個時候則需要抽象出生產甜品,生產咖啡的介面。
  2. ConcreteFactory:具體工廠。分別實現生產甜品的具體工廠,生產咖啡的具體工廠。
  3. AbstractProduct:抽象產品。這裡把甜點抽象成一個產品,把咖啡抽象成一個產品。
  4. Product:具體產品。建立具體的美式咖啡,拿鐵咖啡產品。建立具體的提拉米蘇甜點,抹茶慕斯甜點。

5.2 如何選擇

簡單工廠(Simple Factory)模式:

  1. 定義:簡單工廠模式透過一個工廠類來建立物件,根據傳入的引數或條件決定建立哪種具體物件。
  2. 特點:簡單工廠模式只有一個工廠類,根據條件建立物件,隱藏了物件的建立細節。
  3. 適用場景:當需要根據條件建立不同型別的物件時,可以考慮使用簡單工廠模式。

工廠方法(Factory Method)模式:

  1. 定義:工廠方法模式將物件的建立延遲到子類中,每個子類負責建立自己的物件。
  2. 特點:工廠方法模式透過定義一個抽象的工廠介面和多個具體的工廠類,每個工廠類負責建立一種具體物件。
  3. 適用場景:當需要建立多個相關物件,並且希望將物件的建立邏輯封裝在具體的工廠類中時,可以考慮使用工廠方法模式。

抽象工廠(Abstract Factory)模式:

  1. 定義:抽象工廠模式提供一個介面,用於建立一系列相關或相互依賴的物件,而無需指定具體的類。
  2. 特點:抽象工廠模式透過定義抽象工廠介面和多個具體工廠類,每個具體工廠類負責建立一組相關的物件。
  3. 適用場景:當需要建立一系列相關的物件,並且希望將物件的建立邏輯封裝在具體的工廠類中時,可以考慮使用抽象工廠模式。

5.3 更多內容推薦

模組 描述 備註
GitHub 多個YC系列開源專案,包含Android元件庫,以及多個案例 GitHub
部落格彙總 匯聚Java,Android,C/C++,網路協議,演算法,程式設計總結等 YCBlogs
設計模式 六大設計原則,23種設計模式,設計模式案例,物件導向思想 設計模式
Java進階 資料設計和原理,物件導向核心思想,IO,異常,執行緒和併發,JVM Java高階
網路協議 網路實際案例,網路原理和分層,Https,網路請求,故障排查 網路協議
計算機原理 計算機組成結構,框架,儲存器,CPU設計,記憶體設計,指令程式設計原理,異常處理機制,IO操作和原理 計算機基礎
學習C程式設計 C語言入門級別系統全面的學習教程,學習三到四個綜合案例 C程式設計
C++程式設計 C++語言入門級別系統全面的教學教程,併發程式設計,核心原理 C++程式設計
演算法實踐 專欄,陣列,連結串列,棧,佇列,樹,雜湊,遞迴,查詢,排序等 Leetcode
Android 基礎入門,開源庫解讀,效能最佳化,Framework,方案設計 Android

23種設計模式

23種設計模式 & 描述 & 核心作用 包括
建立型模式
提供建立物件用例。能夠將軟體模組中物件的建立和物件的使用分離
工廠模式(Factory Pattern)
抽象工廠模式(Abstract Factory Pattern)
單例模式(Singleton Pattern)
建造者模式(Builder Pattern)
原型模式(Prototype Pattern)
結構型模式
關注類和物件的組合。描述如何將類或者物件結合在一起形成更大的結構
介面卡模式(Adapter Pattern)
橋接模式(Bridge Pattern)
過濾器模式(Filter、Criteria Pattern)
組合模式(Composite Pattern)
裝飾器模式(Decorator Pattern)
外觀模式(Facade Pattern)
享元模式(Flyweight Pattern)
代理模式(Proxy Pattern)
行為型模式
特別關注物件之間的通訊。主要解決的就是“類或物件之間的互動”問題
責任鏈模式(Chain of Responsibility Pattern)
命令模式(Command Pattern)
直譯器模式(Interpreter Pattern)
迭代器模式(Iterator Pattern)
中介者模式(Mediator Pattern)
備忘錄模式(Memento Pattern)
觀察者模式(Observer Pattern)
狀態模式(State Pattern)
空物件模式(Null Object Pattern)
策略模式(Strategy Pattern)
模板模式(Template Pattern)
訪問者模式(Visitor Pattern)

相關文章