Java23種設計模式案例:抽象工廠模式(abstractFactory)

        抽象工廠模式是全部形態的工廠模式中最爲抽象和最具通常性的一種形態。抽象工廠模式是指當有多個抽象角色時,使用的一種工廠模式。抽象工廠模式能夠向客戶端提供一個接口,使客戶端在沒必要指定產品的具體的狀況下,建立多個產品族中的產品對象。根據里氏替換原則,任何接受父類型的地方,都應當可以接受子類型。所以,實際上系統所須要的,僅僅是類型與這些抽象產品角色相同的一些實例,而不是這些抽象產品的實例。換言之,也就是這些抽象產品的具體子類的實例。工廠類負責建立抽象產品的具體子類的實例。java

        一、工廠方法模式和抽象工廠模式區別


工廠方法模式:
一個抽象產品類,能夠派生出多個具體產品類。   
一個抽象工廠類,能夠派生出多個具體工廠類。   
每一個具體工廠類只能建立一個具體產品類的實例。測試

抽象工廠模式:
多個抽象產品類,每一個抽象產品類能夠派生出多個具體產品類。   
一個抽象工廠類,能夠派生出多個具體工廠類。   
每一個具體工廠類能夠建立多個具體產品類的實例,也就是建立的是一個產品線下的多個產品。   
    
區別:
工廠方法模式只有一個抽象產品類,而抽象工廠模式有多個。   
工廠方法模式的具體工廠類只能建立一個具體產品類的實例,而抽象工廠模式能夠建立多個。
工廠方法建立 "一種" 產品,他的着重點在於"怎麼建立",也就是說若是你開發,你的大量代碼極可能圍繞着這種產品的構造,初始化這些細節上面。也由於如此,相似的產品之間有不少能夠複用的特徵,因此會和模版方法相隨。 spa

抽象工廠須要建立一些列產品,着重點在於"建立哪些"產品上,也就是說,若是你開發,你的主要任務是劃分不一樣差別的產品線,而且儘可能保持每條產品線接口一致,從而能夠從同一個抽象工廠繼承。
對於java來講,你能見到的大部分抽象工廠模式都是這樣的:
---它的裏面是一堆工廠方法,每一個工廠方法返回某種類型的對象。設計

好比說工廠能夠生產鼠標和鍵盤。那麼抽象工廠的實現類(它的某個具體子類)的對象均可以生產鼠標和鍵盤,但可能工廠A生產的是羅技的鍵盤和鼠標,工廠B是微軟的。code

這樣A和B就是工廠,對應於抽象工廠;
每一個工廠生產的鼠標和鍵盤就是產品,對應於工廠方法;對象

用了工廠方法模式,你替換生成鍵盤的工廠方法,就能夠把鍵盤從羅技換到微軟。可是用了抽象工廠模式,你只要換家工廠,就能夠同時替換鼠標和鍵盤一套。若是你要的產品有幾十個,固然用抽象工廠模式一次替換所有最方便(這個工廠會替你用相應的工廠方法)繼承

因此說抽象工廠就像工廠,而工廠方法則像是工廠的一種產品生產線。接口

        二、適用場景

        1)系統不依賴於產品類實例如何被建立,組合和表達的細節。開發

        2)系統的產品有多於一個的產品族,而系統只消費其中某一族的產品(抽象工廠模式的原始用意Unix&Windows)get

        3)同屬於同一個產品族是在一塊兒使用的。這一約束必須在系統的設計中體現出來。

        4)系統提供一個產品類的庫,全部產品以一樣的接口出現,從而使客戶端不依賴於實現。

        三、優勢


1)它分離了具體的類
2)它使得易於交換產品系列
3)它有利於產品的一致性


        四、缺點


1)難以支持新種類的產品,不符合開閉原則

        五、代碼示例

            1)關係圖

                

            2)代碼實現

//定義不一樣的產品之間的必定具有的標準,用interface實現 
//其中的method()方法可看做提取出不一樣產品的共性,如手機都有相似的功能 
interface IProductA{ 
  public void method(); 
} 

interface IProductB{ 
  public void method(); 
} 

//實現了產品標準實現的一系列具體產品 
//因爲已經設計好A1由廠商1生產,故如下輸出代碼有「廠商x」 
class ProductA1 implements IProductA{ 
  public void method() { 
    System.out.println("廠商1    生產ProductA1 ..."); 
  } 
} 

class ProductA2 implements IProductA{ 
  public void method() { 
    System.out.println("廠商2    生產ProductA2 ..."); 
  } 
} 

class ProductB1 implements IProductB{ 
  public void method() { 
    System.out.println("廠商1    生產ProductB1 ..."); 
  } 
} 

class ProductB2 implements IProductB{ 
  public void method() { 
    System.out.println("廠商2    生產ProductB2 ..."); 
  } 
} 

//每一種牌子的產品生產工廠,即不一樣的廠商負責本身牌子產品的生產 
abstract class Factory1{ 
  abstract IProductA getProductA1(); 
  abstract IProductB getProductB1(); 
} 

abstract class Factory2{ 
  abstract IProductA getProductA2(); 
  abstract IProductB getProductB2(); 
} 

//具體的工廠用來生產相關的產品 
class ConcreteFactory1 extends Factory1{ 
  public IProductA getProductA1() { 
    return new ProductA1(); 
  } 
  public IProductB getProductB1() { 
    return new ProductB1(); 
  } 
} 

class ConcreteFactory2 extends Factory2{ 
  public IProductA getProductA2() { 
    return new ProductA2(); 
  } 
  public IProductB getProductB2() { 
    return new ProductB2(); 
  } 
} 

//測試類 
public class Client { 
  public static void main(String[] args) { 
    //廠商1負責生產產品A一、B1 
    Factory1 factory1 = new ConcreteFactory1(); 
    IProductA productA1 = factory1.getProductA1(); 
    IProductB productB1 = factory1.getProductB1(); 
     
    productA1.method(); 
    productB1.method(); 
     
    //廠商2負責生產產品A二、B2 
    Factory2 factory2 = new ConcreteFactoryB(); 
    IProductA productA2 = factory2.getProductA2(); 
    IProductB productB2 = factory2.getProductB2(); 
     
    productA2.method(); 
    productB2.method(); 
  } 
}

執行結果:
廠商1  生產ProductA1 ...
廠商1  生產ProductB1 ...
廠商2  生產ProductA2 ...
廠商2  生產ProductB2 ...
相關文章
相關標籤/搜索