類創建型模式-工廠方法
阿新 • • 發佈:2018-09-17
基於 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. 優缺點
- 優點
- 用戶只需要關心所需產品對應的工廠,無須關心創建細節,甚至無須知道具體產品類的類名。
- 基於工廠角色和產品角色的多態性設計是工廠方法模式的關鍵。
- 在系統中加入新產品時,無須修改抽象工廠和抽象產品提供的接口,無須修改客戶端,符合“開閉原則”。
- 缺點
- 加新產品需編寫新的具體類和對應的工廠類,增加系統復雜性和額外開銷。
- 在客戶端代碼中均使用抽象層進行定義,增加了系統的抽象性和理解難度。
5. 適用場景
- 客戶端不知道它所需要的對象的類,只需要知道對應的工廠類。
- 抽象工廠類通過其子類來指定創建哪個對象,利用對象多態和裏氏變換原則,使得系統更易擴展。
6. 個人理解
- 工廠方法符合“開閉原則”,通過工廠接口的子類來實現系統的可擴展,系統擴展的時候只需添加產品類及其對應的工廠實現類即可。
參考
- Java設計模式-劉偉
類創建型模式-工廠方法