1. 程式人生 > >設計模式 _第二招式_工廠方法模式

設計模式 _第二招式_工廠方法模式

一、定義
工廠方法模式使用的頻率非常高,在我們日常的開發中總能看到它的身影。其定義為:定義一個用於建立物件的介面,讓子類決定例項化哪一個類。工程方法使用一個類的例項化延遲到其子類。
二、程式碼演示
在工廠方法模式中, 抽象產品類Product負責定義產品的共性,實現對事物最抽象的定義;Creater為抽象建立類,已經是抽象工程,具體如何建立產品類是由具體的實現工程ConcreteCreator完成的。工程方法的變種比較多,下面是一個比較通用的原始碼。
工廠方法模式通用的類圖,如下:
這裡寫圖片描述

  • 抽象產品類
public abstract class Product {
   //產品類的公共方法
public void method1(){ //業務邏輯 } //抽象方法 public abstract void method2(); }
  • 具體產品類

具體的產品可以有多個,都繼承於抽象產品類,其原始碼如下:

public class ConcreteProduct1 extends  Product {
    public void  method2(){
        //業務邏輯處理
    }
}
public class ConcreteProduct2 extends Product {
    public
void method2(){ //業務邏輯處理 } }
  • 抽象工廠

抽象工程負責定義產品物件的產生,原始碼如下:

public abstract class Creator {
    public abstract <T extends Product > T createProduct(Class<T> c);
}
  • 具體工廠類

具體如何產生一個產品的物件,是由具體工廠實現的,程式碼如下:

public class ConcreteCreator extends  Creator {
    public
<T extends Product> T createProduct(Class<T> c){ Product product = null ; try { product =(Product)Class.forName(c.getName()).newInstance(); }catch (Exception e){ } return (T)product; } }
  • 場景類

場景負責呼叫方法,程式碼如下:

public class Client {
    public  static  void  main(String args[]){
        Creator  creator = new ConcreteCreator();
        Product  product = creator.createProduct(ConcreteProduct1.class);
        /**
         * 繼續業務處理
         */
    }
}

三、優點

  1. 良好的封裝性,程式碼結構清晰。一個物件建立有條件約束的,如一個呼叫者需要是一個具體的產品物件,只要知道這個產品的類名(或約束字串)就可以了。
    不需要知道過程,降低模組間的耦合。
  2. 工廠方法模式的擴充套件性非常優秀。在增加產品的情況下,只要適當修改具體的工程類或擴充套件一個工程類,就可以“擁抱變化”。
  3. 遮蔽產品類。這一特點非常重要,產品類的實現如何變化,呼叫者都不需要關係,只需要關心產品的介面,只要介面保持不變,系統中的上層模組就不要發生變化。在資料庫開發中,應該能體會到工廠方法模式的好處,我們要將mysql
    資料庫, 切換到oracle 資料庫,只需要修改一下驅動名稱,這就是工廠方法模式的案例。
  4. 工廠方法模式是典型的解耦框架。高層模組值需要知道產品的抽象類,其他的實現類都不用關心,符合迪米特法則,我不需要的就不要去交流;也符合依賴倒置原則,值依賴產品類的抽象;也符合里氏替換原則,使用產品子類替換為父類。

四、缺點
需要謹慎考慮是否需要增加一個工廠類管理,增加程式碼的複雜度。

五、應用場景

  • 工廠方法模式是new一個物件的替代品,所以在所有需要生成物件的地方都可以使用,但是需要謹慎考慮是否需要增加一個工廠類管理,增加程式碼的複雜度。
  • 需要靈活的、可擴充套件的框架時,可以考慮工廠方法模版。萬物皆物件,那萬物就是產品類,例如需要設計一個連線郵件伺服器的框架,有三種網路協議可選擇:POP3、IMAP、HTTP,我們就把這三種連線方法作為產品類,定義一個藉口如IConnectMail,然後定義郵件操作的方法,用不同的方法實現三個具體的產品類,在定義一個工廠方法,按照不同的傳入條件,選擇不同的連線方式。如此設計可做到完美擴充套件,如某些伺服器提供webservice介面,很好,我們只要增加一個產品類就可以了。
  • 工廠方法模版可以用在異構專案中,例如通過webservice與一個非java的專案互動,雖然webservice號稱是可以做到異構系統的同構化,但是實際開發中還是會碰到很多問題,如型別問題、WSDL檔案的支援問題,等等。從WSDL中產生的物件都認為是一個產品,然後有一個具體的工程進行管理,減少與外圍的耦合。
  • 可以使用測試驅動開發的框架下。例如,測試一個類A,就需要把與類A有關聯關係的類B也同步生產出來,我們可以用工廠方法模版把類B虛擬出來,避免類A與類B的耦合。目前由於JMock和EasyMock的誕生,該使用場景已經弱化,讀者可以在遇到此情況時候直接考慮使用JMock和EasyMock。

六、注意事項