工廠模式

1.簡單工廠模式

假如要設計一個類,根據用戶輸入參數的不同,產生不同的對象。
那么可以這樣寫:

public class Chart{
    private String type;
    public Chart{Object[][] data,String type){
        this.type=type;
        if(type.equalsIgnoreCase("aaa")){
            // 第一種類型
        }else if(type.equalsIgnoreCase("bbb")){
            // 第二種類型
        }else if(type.equalsIgnoreCase("ccc")){
            // 第三種類型
        }
    }
    public void display(){
        if(this.type.equalsIgnoreCase("aaa")){
            
        }else if (this.type.equalsIgnoreCase("bbb")){
            
        }else if (this.type.equalsIgnoreCase("ccc")){
            
        }
    }
}

以上代碼的缺點
1.過多的if else 使得代碼很冗余
2.Chart類的職責過重,違反了單一原則
3.需要增加新的type時 需要更改代碼,違反開閉原則
4.與使用者耦合度太高
5.每種type的chart都需要進行初始化,代碼重復

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

簡單工廠模式 又稱 靜態工廠模式
定義一個工廠類,根據參數的不同返回不同的 產品實例 ,產品實例有著共同的父類,即抽象的產品類。

要點:

傳入一個正確的參數就可以獲得一個對應的產品,而且無需知道創建細節。
修改后的代碼 可以這么寫:

abstract class Chart{
    abstract void methodDiff();//每個type的chart的特有方法
    public void methodSame(){  //所有type的chart的相同方法
        
    }
}
class ChartA extends Chart{     //具體的chartA
    public void methodDiff(){
        
    }
}   
class ChartB extends Chart{     //具體的chartB
    public void methodDiff(){
        
    }
}
class ChartFactory{
    public static Chart getChart(String type){
        Chart chart=null;
        if(type.equalsIgnoreCase(“aaa”)){
            chart=new ChartA();
        }else if(type.equalsIgnoreCase("bbb")){
            chart=new ChartB();
        }
        return chart;
    }
}

// 客戶端獲取產品時 直接調用
Chart chart=ChartFactory.getChart("aaa");

總結

將對象的創建和使用分離
優點
1.對象的創建 和 使用分離

2.用戶不需要知道創建的具體對象

3.可以引入配置文件,可以在不改變代碼的情況下,添加或更換新的產品類

缺點

工廠類職責過重,產品類過多是會導致工廠類過于復雜。
違反開閉原則。

使用場景

產品類不多
客戶端并不關心產品類如何創建

2.工廠方法模式

interface Product{
    public void Method();
}
class ProductA implements Product{
    public void Method(){
        //產品A
    }
}
class ProductB implements Product{
    public void Method(){
        //產品B
    }
}
// 若A B產品初始化都需要 經歷復雜的初始化
class ProductFactory{
    public static Product getProduct(String type){
        Product p=null;
        if(type.equals("a")){
            // 消耗大量資源的操作
            p=new ProductA();
        }else {
            // 消耗大量資源的操作
            p=new ProductB();
        }
        return p;
    }
}
// 大量操作寫到構造方法中就不合適

此時可以使用 工廠方法模式。
又名 虛擬構造器模式(Virtual Constructor Pattern)或多態工廠模式(Polymorphic Factory Pattern),定義了一個創建對象的接口,但由子類決定要實例化的類是哪一個。

interface Factory {
    public Product getProduct();
}
class AFactory implements Factory {
    public Product getProduct(){
        // 消耗大量資源的操作 
        return new ProductA();//亦可以 不返回對象,直接在此調用Method()方法,即對使用者隱藏了工廠方法 即隱藏了具體的對象。也可以通過配置文件寫入類名的方法,在此解析配置文件加載類名 然后反射產生對象
    }   
}
class BFactory implements Factory {
    public Product getProduct(){ //亦可以弄幾個多態方法,來生成產品
        // 消耗大量資源的操作
        return new ProductB(); 
    }
}

工廠方法模式的總結:
優點
1. 有新產品時,只需添加新的產品類和工廠類,無需修改之前的代碼 符合 開閉原則
2. 工廠類 和 產品類 都可以進行多態設計, 工廠可以自己確定創建哪個產品
3. 可以向調用者隱藏具體產品類,用戶不知道到底創建了哪一個產品類。用戶只關心對應的工廠,

缺點

  1. 需要引入抽象層,用戶均使用抽象層的定義
  2. 在添加新產品時,需要編寫新的具體產品類,而且還要提供與之對應的具體工廠類

3.抽象工廠模式

工廠方法模式 的情況下,每個工廠只生成一種產品。但是假如一個工廠要生成n種產品,而且有很多工廠時,那么 工廠方法模式 便不再合適。

此時可以使用抽象工廠方法。

若有 m個工廠,每個工廠都會生成相同的n種產品 。若按照一個工廠一種產品的想法,則需 m*n個工廠。

m個工廠,每個工廠稱為一個產品族。
n種產品,稱為n個產品等級。

抽象工廠方法的思路是:

    AbstractFactory 定義生成這n種產品的方法,
        | ProductA  createProductA();
        | ProductB  createProductB();
        | ProductC  createProductC();
        
    AbstractProduct  抽象的產品
    
    ConcreteFactoryA  extends AbstractFactory   具體工廠A
        |  ProductA  createProductA();
        |  ProductB  createProductB();
        |  ProductC  createProductC();
    ConcreteFactoryB  extends AbstractFactory   具體工廠B
        |  ProductA  createProductA();
        |  ProductB  createProductB();
        |  ProductC  createProductC();

即 定義m個工廠,均繼承自抽象工廠,所以實現了構造各種產品的方法,產生了這n中產品等級的所有產品。這種寫法,則需 m個工廠。

總結:
優點 :

  1. 抽象工廠模式隔離了具體類的生成,改變工廠類很容易。
  2. 保證客戶端使用的是同一個產品族的對象,即同一個工廠的產品
  3. 增加新的產品族非常容易, 符合開閉原則

缺點:
增加新產品不方便,不符合開閉原則

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容