工廠模式

📢 本文由 gemini-3-flash-preview 翻譯

簡單工廠模式

簡單工廠模式屬於建立型模式,但不屬於 23 種設計模式之一

定義:定義一個工廠類別,它可以根據參數的不同傳回不同類別的實例,被建立的實例通常都具有共同的父類別

在簡單工廠模式中用於建立實例的方法通常為靜態 (static) 方法,因此簡單工廠模式又稱為靜態工廠方法 (Static Factory Method)

需要什麼產品就傳入產品對應的參數,就可以獲取所需要的產品物件,而無需知道其實作過程

例如:有一家水餃店,當客戶需要某種水餃時,水餃店生成對應的水餃給客戶。這裡就可以把水餃店看成工廠 (Factory),水餃看成產品 (Product),水餃的名稱看成參數,水餃店根據不同的參數傳回不同的水餃

比如:客戶想要韭菜水餃,這裡韭菜就是參數,水餃店會根據參數韭菜傳回韭菜水餃 (水餃店有韭菜水餃的前提下)

簡單工廠模式

三類角色:

  1. 工廠 (核心)

​ 負責實作建立所有產品的內部邏輯,工廠類別可以被外界直接呼叫,建立所需物件

  1. 抽象產品

​ 工廠類別所建立的所有物件的父類別,封裝了產品物件的公用方法,所有的具體產品為其子類別物件

  1. 具體產品

​ 簡單工廠模式的建立目標,所有被建立的物件都是某個具體類別的實例

例子

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
public class SimpleFactory{
    public static void main(String[] args){
        Product productA = Factory.createProduct("A");
        productA.info();
        // ...
    }
}

abstract class Product{
    public abstract void info();
}

class ProductA extends Product{
    @Override
    public void info(){
        System.out.println("A");
    }
}

class ProductB extends Product{
    @Override
    public void info(){
        System.out.println("B");
    }
}

class Factory{
    public static Product creatProduct(String type){
        Product p = null;
        // 此處未考慮異常情況以及處理
        switch(type){
            case "A":
                p = new ProductA();
                break;
            case "B":
                p = new ProductB();
                break;
            default:
                System.out.println("Please try again");
                break;
        }
        
        return p;
    }
}

當增加產品時,將更改工廠,違反了 開放 - 封閉原則

工廠方法模式

Factory Method Pattern 類別建立型模式

意圖

定義一個用於建立物件的介面,讓子類別決定實例化哪一個類別。Factory Method 使一個類別的實例化延遲到其子類別

結構

工廠方法模式

其中:

  • Product 定義工廠方法所建立的物件的介面
  • ConcreteProduct 實作 Product 介面
  • Creator 宣告工廠方法,該方法傳回一個 Product 類型的物件,Creator 也可以定義一個工廠方法的預設實作,它傳回一個預設的 ConcreteProduct 物件,可以呼叫工廠方法以建立一個 Product 物件
  • ConcreteCreator 重新定義工廠方法以傳回一個 ConcreteProduct 實例

適用性

Factory Method 模式適用於:

  • 當一個類別不知道它所必須建立的物件的類別的時候
  • 當一個類別希望由它的子類別來指定它所建立的物件的時候
  • 當類別將建立物件的職責委託給多個幫助子類別中的某一個,並且你希望將哪一個幫助子類別是代理者這一資訊局部化的時候

例子

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
// 在上一個程式碼的基礎上修改
public class FactoryMethod{
    public static void main(String[] args){
        Factory factoryA = new FactoryA();
        
        //Product productA = Factory.createProduct("A");
        Product productA = factoryA.createProduct();
        productA.info();
        // ...
    }
}
// 抽象類別改介面
// abstract class Product
interface Product{
    // public abstract void info();
    public void info();
}
// 繼承改實作
// class ProductA extends Product{
class ProductA implements Product{
    @Override
    public void info(){
        System.out.println("A");
    }
}
// 繼承改實作
// class ProductB extends Product{
class ProductB implements Product{
    @Override
    public void info(){
        System.out.println("B");
    }
}
// 實體類別改介面
// class Factory
interface Factory{
    public Product creatProduct();
}
// 增加介面實作
class FactoryA implements Factory{
    @Override
    public Product createProduct(){
        return new ProductA();
    }
}

class FactoryB implements Factory{
    @Override
    public Product createProduct(){
        return new ProductB();
    }
}

抽象工廠模式

Abstract Factory Pattern 物件建立型模式

意圖

提供一個建立一系列相關或相互依賴物件的介面,而無需指定它們具體的類別

結構

抽象工廠模式

其中:

  • AbstractFactory 宣告一個建立抽象產品物件的操作介面
  • ConcreteFactory 實作建立具體產品物件的操作
  • AbstractProduct 為一類產品物件宣告一個介面
  • ConcreteProduct 定義一個將被相應的具體工廠建立的產品物件,實作 AbstractProduct 介面
  • Client 僅使用由 AbstractFactory 和 AbstractProduct 類別宣告的介面

適用性

Abstract Factory 模式適用於:

  • 一個系統要獨立於它的產品的建立、組合和表示時
  • 一個系統要由多個產品系列中的一個來配置時
  • 當要強調一系列相關的產品物件的設計以便進行聯合使用時
  • 當提供一個產品類別庫,只想顯示它們的介面而不是實作時

例子

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
public class AbstractFactory{
    public static void main(String[] args){
        Factory factory1 = new Factory1();
        
        ProductA productA = factory1.createProductA();
        productA.info();
        // ...
    }
}

interface ProductA{
    public void info();
}

class ProductA1 implements ProductA{
    @Override
    public void info(){
        System.out.println("A1");
    }
}

class ProductA2 implements ProductA{
    @Override
    public void info(){
        System.out.println("A2");
    }
}

interface ProductB{
    public void info();
}

class ProductB1 implements ProductB{
    @Override
    public void info(){
        System.out.println("B1");
    }
}

class ProductB2 implements ProductB{
    @Override
    public void info(){
        System.out.println("B2");
    }
}

interface Factory{
    public ProductA creatProductA();
    public ProductB creatProductB();
}

class Factory1 implements Factory{
    @Override
    public ProductA createProductA(){
        return new ProductA1();
    }
    
    @Override
    public ProductB createProductB(){
        return new ProductB1();
    }
}

class Factory2 implements Factory{
    @Override
    public ProductA createProductA(){
        return new ProductA2();
    }
    
    @Override
    public ProductB createProductB(){
        return new ProductB2();
    }
}