設計模式-----工廠方法模式

工廠方法模式

前言

在前面博主寫的文章:設計模式-----簡單工廠模式,發現簡單工廠模式存在一系列問題:html

  • 工廠類集中了全部實例(產品)的建立邏輯,一旦這個工廠不能正常工做,整個系統都會受到影響
  • 違背「開放 - 關閉原則」,一旦添加新產品就不得不修改工廠類的邏輯,這樣就會形成工廠邏輯過於複雜
  • 簡單工廠模式因爲使用了靜態工廠方法,靜態方法不能被繼承和重寫,會形成工廠角色沒法造成基於繼承的等級結構

爲了解決上述的問題,咱們又使用了一種新的設計模式:工廠方法模式java

1.介紹

1.1 定義

工廠方法模式,又稱工廠模式、多態工廠模式和虛擬構造器模式,經過定義工廠父類負責定義建立對象的公共接口,而子類則負責生成具體的對象數據庫

1.2 主要做用

將類的實例化(具體產品的建立)延遲到工廠類的子類(具體工廠)中完成,即由子類來決定應該實例化(建立)哪個類設計模式

1.3 解決的問題

工廠一旦須要生產新產品就須要修改工廠類的方法邏輯,違背了「開放 - 關閉原則ide

  1. 即簡單工廠模式的缺點
  2. 之因此能夠解決簡單工廠的問題,是由於工廠方法模式把具體產品的建立推遲到工廠類的子類(具體工廠)中,此時工廠類再也不負責全部產品的建立,而只是給出具體工廠必須實現的接口,這樣工廠方法模式在添加新產品的時候就不修改工廠類邏輯而是添加新的工廠子類,符合開放封閉原則,克服了簡單工廠模式中缺點

2.模式原理

2.1 UML類圖

2.2 模式組成

組成(角色) 關係 做用
抽象產品(Product) 具體產品的父類 描述具體產品的公共接口
具體產品(Concrete Product) 抽象產品的子類;工廠類建立的目標類 描述生產的具體產品
抽象工廠(Creator) 具體工廠的父類 描述具體工廠的公共接口
具體工廠(Concrete Creator) 抽象工廠的子類;被外界調用 描述具體工廠;實現FactoryMethod工廠方法建立產品的實例

2.3 使用步驟

  1. 建立抽象工廠類,定義具體工廠的公共接口
  2. 建立抽象產品類 ,定義具體產品的公共接口
  3. 建立具體產品類(繼承抽象產品類) & 定義生產的具體產品
  4. 建立具體工廠類(繼承抽象工廠類),定義建立對應具體產品實例的方法
  5. 外界經過調用具體工廠類的方法,從而建立不一樣具體產品類的實例

3.實例講解

3.1 實例概況

  • 背景:小成有一間塑料加工廠(僅生產A類產品);隨着客戶需求的變化,客戶須要生產B類產品
  • 衝突:改變原有塑料加工廠的配置和變化很是困難,假設下一次客戶須要再發生變化,再次改變將增大很是大的成本
  • 解決方案:小成決定置辦塑料分廠B來生產B類產品

3.2 使用步驟

3.2.1:建立抽象工廠類,定義具體工廠的公共接口

abstract class Factory{
    public abstract Product Manufacture();
}

3.2.2 建立抽象產品類 ,定義具體產品的公共接口

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

3.2.3 建立具體產品類(繼承抽象產品類), 定義生產的具體產品

//具體產品A類
class  ProductA extends  Product{
    @Override
    public void Show() {
        System.out.println("生產出了產品A");
    }
}

//具體產品B類
class  ProductB extends  Product{

    @Override
    public void Show() {
        System.out.println("生產出了產品B");
    }
}

3.2.4 建立具體工廠類(繼承抽象工廠類),定義建立對應具體產品實例的方法

//工廠A類 - 生產A類產品
class  FactoryA extends Factory{
    @Override
    public Product Manufacture() {
        return new ProductA();
    }
}

//工廠B類 - 生產B類產品
class  FactoryB extends Factory{
    @Override
    public Product Manufacture() {
        return new ProductB();
    }
}

3.2.5 外界經過調用具體工廠類的方法,從而建立不一樣*具體產品類的實例

//生產工做流程
public class FactoryPattern {
    public static void main(String[] args){
        //客戶要產品A
        FactoryA mFactoryA = new FactoryA();
        mFactoryA.Manufacture().Show();

        //客戶要產品B
        FactoryB mFactoryB = new FactoryB();
        mFactoryB.Manufacture().Show();
    }
}

結果:

生產出了產品A
生產出了產品B

4.優勢

  • 更符合開-閉原則
    新增一種產品時,只須要增長相應的具體產品類和相應的工廠子類便可

簡單工廠模式須要修改工廠類的判斷邏輯ui

  • 符合單一職責原則
    每一個具體工廠類只負責建立對應的產品

簡單工廠中的工廠類存在複雜的switch邏輯判斷設計

  • 不使用靜態工廠方法,能夠造成基於繼承的等級結構

簡單工廠模式的工廠類使用靜態工廠方法code

總結htm

工廠模式能夠說是簡單工廠模式的進一步抽象和拓展,在保留了簡單工廠的封裝優勢的同時,讓擴展變得簡單,讓繼承變得可行,增長了多態性的體現對象

5.缺點

  • 添加新產品時,除了增長新產品類外,還要提供與之對應的具體工廠類,系統類的個數將成對增長,在必定程度上增長了系統的複雜度;同時,有更多的類須要編譯和運行,會給系統帶來一些額外的開銷
  • 因爲考慮到系統的可擴展性,須要引入抽象層,在客戶端代碼中均使用抽象層進行定義,增長了系統的抽象性和理解難度,且在實現時可能須要用到DOM、反射等技術,增長了系統的實現難度
  • 雖然保證了工廠方法內的對修改關閉,但對於使用工廠方法的類,若是要更換另一種產品,仍然須要修改實例化的具體工廠類

  • 一個具體工廠只能建立一種具體產品

6.應用場景

  • 當一個類不知道它所須要的對象的類時
    在工廠方法模式中,客戶端不須要知道具體產品類的類名,只須要知道所對應的工廠便可
  • 當一個類但願經過其子類來指定建立對象時
    在工廠方法模式中,對於抽象工廠類只須要提供一個建立產品的接口,而由其子類來肯定具體要建立的對象,利用面向對象的多態性和里氏代換原則,在程序運行時,子類對象將覆蓋父類對象,從而使得系統更容易擴展
  • 將建立對象的任務委託給多個工廠子類中的某一個,客戶端在使用時能夠無須關心是哪個工廠子類建立產品子類,須要時再動態指定,可將具體工廠類的類名存儲在配置文件或數據庫中
相關文章
相關標籤/搜索