1. 程式人生 > >設計模式(二)工廠方法模式

設計模式(二)工廠方法模式

設計模式(二):工廠方法模式

Github

關於23設計模式的講解檔案已經放在我的GitHub上,歡迎大家Fork和Star

模式動機

​ 在簡單工廠模式中,如果在原來的實現的基礎上,我們再增加一個產品類的實現,那麼我們必須在原來的工廠方法裡修改工廠類的原始碼.那麼有沒有更好的方法,可以不修改工廠類的原始碼而進行動態的可擴充套件呢?今天我們將要介紹的設計模式之工廠方法模式,就是這樣的一個很好的設計思路:將工廠類進行抽象,根據不同的產品建立不同的工廠類,如果動態的增加了一個產品,我們只需要實現這個產品的具體類的工廠類即可。

模式定義

​ 工廠方法模式也稱為工廠模式,屬於建立型模式。在工廠方法模式中,工廠父類負責定義建立產品物件的公共介面,而工廠子類則負責生成具體的產品物件,這樣做的目的是將產品類的例項化操作延遲到工廠子類中完成,即通過工廠子類來確定究竟應該例項化哪一個具體產品類。

模式結構

工廠方法模式包含如下角色:

​ Product:抽象產品

​ ConcreteProduct:具體產品

​ Factory:抽象工廠

ConcreteFactory:具體工廠

這裡寫圖片描述

時序圖

這裡寫圖片描述

程式碼示例

這裡我們通過一個具體的例項來進行講解,在我們編寫程式的過程中,我們經常會遇到各種日誌,有檔案的日誌,資料庫的日誌等。我們這裡建立兩個抽象的類Log和LogFactory

package cn.edu.hust.factory;

public abstract class Log {
    public abstract void writeLog
(); }
package cn.edu.hust.factory;

public abstract class LogFactory {
    public abstract Log createLog();
}

接下來就是建立Log的實現類:

package cn.edu.hust.factory;

public class FileLog extends Log{
    public void writeLog() {
        System.out.println("檔案日誌。。。。");
    }
}
package cn.edu.hust.factory;

public
class FileLog extends Log{ public void writeLog() { System.out.println("檔案日誌。。。。"); } }

然後就是生產兩種日誌的工廠類:

package cn.edu.hust.factory;

public class FileLogFactory extends LogFactory{

    public Log createLog() {
        return new FileLog();
    }
}
package cn.edu.hust.factory;

public class DataBaseLogFactory extends LogFactory{
    public Log createLog() {
        return new DataBaseLog();
    }
}

在實際的應用中,我們根據需求使用不同的工廠生產出不同的物件。這裡,如果要有一個WebLog類,我們可以繼承Log類,然後建立一個WebLogFactory,只是動態的擴充套件不需要修改任何的系統程式碼。

工廠模式優點

  • 在工廠方法模式中,工廠方法用來建立客戶所需要的產品,同時還向客戶隱藏了哪種具體產品類將被例項化這一細節,使用者只需要關心所需產品對應的工廠,無須關心建立細節,甚至無須知道具體產品類的類名。
  • 基於工廠角色和產品角色的多型性設計是工廠方法模式的關鍵。它能夠使工廠可以自主確定建立何種產品物件,而如何建立這個物件的細節則完全封裝在具體工廠內部。工廠方法模式之所以又被稱為多型工廠模式,是因為所有的具體工廠類都具有同一抽象父類。
  • 使用工廠方法模式的另一個優點是在系統中加入新產品時,無須修改抽象工廠和抽象產品提供的介面,無須修改客戶端,也無須修改其他的具體工廠和具體產品,而只要新增一個具體工廠和具體產品就可以了。這樣,系統的可擴充套件性也就變得非常好,完全符合“開閉原則”。

工廠模式缺點

  • 在新增新產品時,需要編寫新的具體產品類,而且還要提供與之對應的具體工廠類,系統中類的個數將成對增加,在一定程度上增加了系統的複雜度,有更多的類需要編譯和執行,會給系統帶來一些額外的開銷。
  • 由於考慮到系統的可擴充套件性,需要引入抽象層,在客戶端程式碼中均使用抽象層進行定義,增加了系統的抽象性和理解難度,且在實現時可能需要用到DOM、反射等技術,增加了系統的實現難度。

適用場景

在以下情況下可以使用工廠方法模式:

  • 一個類不知道它所需要的物件的類:在工廠方法模式中,客戶端不需要知道具體產品類的類名,只需要知道所對應的工廠即可,具體的產品物件由具體工廠類建立;客戶端需要知道建立具體產品的工廠類。
  • 一個類通過其子類來指定建立哪個物件:在工廠方法模式中,對於抽象工廠類只需要提供一個建立產品的介面,而由其子類來確定具體要建立的物件,利用面向物件的多型性和里氏代換原則,在程式執行時,子類物件將覆蓋父類物件,從而使得系統更容易擴充套件。
  • 將建立物件的任務委託給多個工廠子類中的某一個,客戶端在使用時可以無須關心是哪一個工廠子類建立產品子類,需要時再動態指定,可將具體工廠類的類名儲存在配置檔案或資料庫中。

微信公眾號

有興趣的同學可以關注小編喲!
這裡寫圖片描述