設計模式 - 簡單工廠模式

f1uLove發表於2018-10-28

簡單工廠模式嚴格來說並不是一個設計模式,反而較像是一種程式設計習慣。

定義

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

結構

簡單工廠

簡單工廠包含了一下角色:

  • Factory: 工廠角色 負責根據不同的引數建立不同的例項。

  • IProduct: 抽象產品角色 所有產品例項的介面,負責描述所有產品例項的行為。

  • Product(A B ..): 具象產品角色 所有產品的例項,實現了抽象產品定義的程式碼

場景示例:

簡單工廠應用的場景比較對,那麼就根據作者的理解,拿作者工作中遇到的場景需求舉例: 平臺做一個機票代購業務,對接了兩個供應商A、B,使用者選擇完機票後,平臺拿著機票去供應商下單。下單時根據機票由那個供應商提供去相應的供應商去下單。

第一步就是定義一個下單介面。

public interface IVender {
    /**
     * 供應商下單方法
     */
    void order();
}

複製程式碼

然後分別實現A、B供應商的下單方法。

public class VendorA implements IVender {
    @Override
    public void order() {
        // 業務邏輯處理
        System.out.println("A供應商下單成功,下單時間" + new Date());
    }
}
複製程式碼
public class VendorB implements IVender {
    @Override
    public void order() {
        // 業務邏輯處理
        System.out.println("B供應商下單成功,下單時間:" + new Date());
    }
}
複製程式碼

接著定義一個工廠類,根據傳入的不同引數請求,分別建立不同的供應商例項並返回,若碰到無效的引數,則丟擲異常。

public class VendorFactory {

    public static IVender createVendor(String type) {
        switch (type) {
            case "A":
                return new VendorA();
            case "B":
                return new VendorB();
            default:
                throw new RuntimeException("供應商不存在");
        }
    }
}
複製程式碼

最後,由我們客戶端進行呼叫:

public class Client {
    public static void main(String[] args) {
        String type = "A";
        IVender iVender = VendorFactory.createVendor(type);
        iVender.order();
    }
}
複製程式碼

如果我們都寫在一個類中:

public class Client2 {
    private static final String TYPE_A = "A";
    private static final String TYPE_B = "B";

    public static void main(String[] args) {
        String type = "A";
        if (Objects.equals(TYPE_A, type)) {
            // A 供應商下單邏輯處理
            System.out.println("A供應商下單成功,下單時間" + new Date());
        } else if (Objects.equals(TYPE_B, type)) {
            // B 供應商下單邏輯處理
            System.out.println("A供應商下單成功,下單時間" + new Date());
        } else {
            throw new RuntimeException("供應商不存在");
        }
    }
}
複製程式碼

第二種寫法,供應商下單邏輯較多的話會使客戶端變得十分複雜,後期維護起來也將是一個災難。如果新增加一個供應商,將會對這個類有這較大的改動,很明顯的違反了開閉原則迪米特法則

優點

  • 工廠類含有必要的判斷邏輯,可以決定在什麼時候建立哪一個產品類的例項,客戶端可以免除直接建立產品物件的責任,而僅僅“消費”產品;簡單工廠模式通過這種做法實現了對責任的分割,它提供了專門的工廠類用於建立物件。
  • 客戶端無須知道所建立的具體產品類的類名,只需要知道具體產品類所對應的引數即可,對於一些複雜的類名,通過簡單工廠模式可以減少使用者的記憶量。
  • 通過引入配置檔案,可以在不修改任何客戶端程式碼的情況下更換和增加新的具體產品類,在一定程度上提高了系統的靈活性。

缺點

  • 由於工廠類集中了所有產品建立邏輯,一旦不能正常工作,整個系統都要受到影響。
  • 使用簡單工廠模式將會增加系統中類的個數,在一定程式上增加了系統的複雜度和理解難度。
  • 系統擴充套件困難,一旦新增新產品就不得不修改工廠邏輯,在產品型別較多時,有可能造成工廠邏輯過於複雜,不利於系統的擴充套件和維護。
  • 簡單工廠模式由於使用了靜態工廠方法,造成工廠角色無法形成基於繼承的等級結構。

使用場景

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

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

總結

  • 建立型模式對類的例項化過程進行了抽象,能夠將物件的建立與物件的使用過程分離。
  • 簡單工廠模式又稱為靜態工廠方法模式,它屬於類建立型模式。在簡單工廠模式中,可以根據引數的不同返回不同類的例項。簡單工廠模式專門定義一個類來負責建立其他類的例項,被建立的例項通常都具有共同的父類。
  • 簡單工廠模式包含三個角色:工廠角色負責實現建立所有例項的內部邏輯;抽象產品角色是所建立的所有物件的父類,負責描述所有例項所共有的公共介面;具體產品角色是建立目標,所有建立的物件都充當這個角色的某個具體類的例項。
  • 簡單工廠模式的要點在於:當你需要什麼,只需要傳入一個正確的引數,就可以獲取你所需要的物件,而無須知道其建立細節。
  • 簡單工廠模式最大的優點在於實現物件的建立和物件的使用分離,將物件的建立交給專門的工廠類負責,但是其最大的缺點在於工廠類不夠靈活,增加新的具體產品需要修改工廠類的判斷邏輯程式碼,而且產品較多時,工廠方法程式碼將會非常複雜。
  • 簡單工廠模式適用情況包括:工廠類負責建立的物件比較少;客戶端只知道傳入工廠類的引數,對於如何建立物件不關心。

相關文章