1. 程式人生 > >類創建型模式-工廠方法

類創建型模式-工廠方法

基於 book 系統擴展 聲明 子類 code logger 關心 原則

簡單工廠模式最大的缺點是當有新產品要加入到系統中時,必須修改工廠類,需要在其中加入必要的業務邏輯,這違背了“開閉原則”。此外,在簡單工廠模式中,所有的產品都由同一個工廠創建,工廠類職責較重,業務邏輯較為復雜,具體產品與工廠類之間的耦合度高,嚴重影響了系統的靈活性和擴展性,而工廠方法模式則可以很好地解決這一問題。

1. 定義

工廠方法模式(Factory Method Pattern):定義一個用於創建對象的接口,讓子類決定將哪一個類實例化。工廠方法模式讓一個類的實例化延遲到其子類。工廠方法模式又簡稱為工廠模式(Factory Pattern),又可稱作虛擬構造器模式(Virtual Constructor Pattern)或多態工廠模式(Polymorphic Factory Pattern)。工廠方法模式是一種類創建型模式。

2. 結構

工廠方法模式提供一個抽象工廠接口來聲明抽象工廠方法,而由其子類來具體實現工廠方法,創建具體的產品對象。工廠方法模式結構如圖所示:

技術分享圖片

  • Product(抽象產品):它是定義產品的接口,是工廠方法模式所創建對象的超類型,也就是產品對象的公共父類。
  • ConcreteProduct(具體產品):它實現了抽象產品接口,某種類型的具體產品由專門的具體工廠創建,具體工廠和具體產品之間一一對應。
  • Factory(抽象工廠):在抽象工廠類中,聲明了工廠方法(Factory Method),用於返回一個產品。抽象工廠是工廠方法模式的核心,所有創建對象的工廠類都必須實現該接口。
  • ConcreteFactory(具體工廠):它是抽象工廠類的子類,實現了抽象工廠中定義的工廠方法,並可由客戶端調用,返回一個具體產品類的實例。

3. 代碼實現

產品接口

public interface Logger {
    void writeLog();
}

產品實現類1

public class FileLogger implements Logger {

    @Override
    public void writeLog() {
        System.out.println("寫文件Log");
    }
}

產品實現類2

public class DatabaseLogger implements Logger {

    @Override
    public void writeLog() {
        System.out.println("寫數據庫log");
    }
}

工廠接口

public interface LoggerFactory {
    Logger createLogger();

    //重載的工廠方法
    Logger createLogger(String args);

    //使用該函數可隱藏工廠方法
    void writeLog();
}

工廠實現類1

public class FileLoggerFactory implements LoggerFactory {

    @Override
    public Logger createLogger() {
        Logger logger = new FileLogger();
        //進行相應的初始化操作
        return logger;
    }

    @Override
    public Logger createLogger(String args) {
        return null;
    }
    @Override
    public void writeLog() {
        Logger logger = new FileLogger();
        logger.writeLog();
    }
}

工廠實現類2

public class DatabaseLoggerFactory implements LoggerFactory {

    @Override
    public Logger createLogger() {
        Logger logger = new DatabaseLogger();
        //進行相應的初始化操作
        return logger;
    }

    @Override
    public Logger createLogger(String args) {
        return null;
    }

    @Override
    public void writeLog() {
        Logger logger = new DatabaseLogger();
        logger.writeLog();
    }
}

測試類

public class Test {

    public static void main(String[] args) {
        //這邊可以利用反射從配置文件讀取類名來獲得具體的類
        //Class c=Class.forName(cName);
        //Object obj=c.newInstance();

        //調用工廠方法
        LoggerFactory loggerFactory = new FileLoggerFactory();
        Logger logger = loggerFactory.createLogger();
        logger.writeLog();

        //可在工廠接口中提供產品具體的函數來隱藏工廠方法的調用
        LoggerFactory loggerFactory2 = new DatabaseLoggerFactory();
        loggerFactory2.writeLog();
    }
}
//寫文件Log
//寫數據庫log

4. 優缺點

  • 優點
  1. 用戶只需要關心所需產品對應的工廠,無須關心創建細節,甚至無須知道具體產品類的類名。
  2. 基於工廠角色和產品角色的多態性設計是工廠方法模式的關鍵。
  3. 在系統中加入新產品時,無須修改抽象工廠和抽象產品提供的接口,無須修改客戶端,符合“開閉原則”。
  • 缺點
  1. 加新產品需編寫新的具體類和對應的工廠類,增加系統復雜性和額外開銷。
  2. 在客戶端代碼中均使用抽象層進行定義,增加了系統的抽象性和理解難度。

5. 適用場景

  1. 客戶端不知道它所需要的對象的類,只需要知道對應的工廠類。
  2. 抽象工廠類通過其子類來指定創建哪個對象,利用對象多態和裏氏變換原則,使得系統更易擴展。

6. 個人理解

  1. 工廠方法符合“開閉原則”,通過工廠接口的子類來實現系統的可擴展,系統擴展的時候只需添加產品類及其對應的工廠實現類即可。

參考

  1. Java設計模式-劉偉

類創建型模式-工廠方法