-
- 簡介
- 結構和實作
- 執行個體
- 工廠方法重載
- 工廠方法隐藏
- 優缺點和和适用環境
- jdk中的應用
簡介
工廠方法模式(Factory Method Pattern):定義一個用于建立對象的接口,但是讓子類決定将哪一個類執行個體化,即讓一個類的執行個體化延遲到子類。
- 工廠方法模式引入抽象工廠類,由其子類建立執行個體,可以添加産品和對應的具體工廠類,在不修改工廠類源代碼的情況下引入新的産品類。又稱虛拟構造器模式或者多态工廠模式。
結構和實作
- 角色包括:
- 抽象産品:建立的對象的超類。
- 具體産品:建立的對象,與具體工廠一一對應。
- 抽象工廠:具體工廠的超類,聲明工廠方法。
- 具體工廠:實作工廠方法,建立對象。
- 結構。
- 用戶端調用。
- 具體工廠類可以通過配置檔案和反射更換,更加符合開閉原則。
……
Factory factory;
factory = new ConcreteFactory(); //可通過配置檔案和反射實作
Product product;
product = factory.factoryMethod();
……
執行個體
- 開發日志記錄儀,通過多種途徑儲存系統的日志,如檔案或者資料庫。使用者需要通過修改配置檔案靈活更換日志的記錄方法,并且日志記錄器的初始化工作較為複雜且容易出錯。
- 日志記錄器結構。
- 資料庫日志記錄器工廠類、檔案日志記錄器工廠類。
public class DatabaseLoggerFactory implements LoggerFactory {
public Logger createLogger() {
//連接配接資料庫,代碼省略
//建立資料庫日志記錄器對象
Logger logger = new DatabaseLogger();
//初始化資料庫日志記錄器,代碼省略
return logger;
}
}
public class FileLoggerFactory implements LoggerFactory {
public Logger createLogger() {
//建立檔案日志記錄器對象
Logger logger = new FileLogger();
//建立檔案,代碼省略
return logger;
}
}
public class Client {
public static void main(String args[]) {
LoggerFactory factory;
Logger logger;
factory = new FileLoggerFactory(); //可引入配置檔案實作
logger = factory.createLogger();
logger.writeLog();
}
}
工廠方法重載
- 可以使用重載的工廠方法,使用戶端通過多種方式初始化同一個産品類。這樣可以滿足對象的多樣化建立需求。
工廠方法隐藏
- 可以将産品的業務方法放入抽象工廠類中,使用戶端無需調用工廠方法建立産品,而是直接使用工廠對象調用産品的業務方法。
- 抽象工廠類中放入業務方法。
public abstract class LoggerFactory {
//在工廠類中直接調用日志記錄器類的業務方法writeLog()
public void writeLog() {
Logger logger = this.createLogger();
logger.writeLog();
}
public abstract Logger createLogger();
}
public class Client {
public static void main(String args[]) {
LoggerFactory factory;
factory = (LoggerFactory)XMLUtil.getBean();
factory.writeLog(); //直接使用工廠對象來調用産品對象的業務方法
}
}
優缺點和和适用環境
- 優點:
- 實作對象的建立和使用分離。使用者隻需要使用對應的工廠,而無須知道産品的類名和建立過程。利用多态性調用具體工廠方法建立對應的産品。
- 加入新産品時無須修改抽象工廠。隻需加入新的産品和對應具體工廠即可,完全符合開閉原則。
- 缺點:
- 增加系統複雜度。增加産品時需要增加新的産品和對應的具體工廠,類的個數成對增加。
- 增加系統抽象性。引入抽象層并針對抽象程式設計。
- 适用環境:
- 用戶端無須知道所需要的類,隻需要知道對應的工廠即可。
- 建立對象較為複雜,需要通過具體工廠類建立具體産品,利用面向對象的多态性和裡氏替換原則,運作時子類替換基類。
jdk中的應用
- ArrayList和Vector的iterator方法,建立各自的疊代器對象。
public Iterator<E> iterator() {
return new Itr();
}
private class Itr implements Iterator<E> {
......
}
-