介紹
工廠方法是一種建立型設計模式,其在父類中提供一個建立物件的方法,允許子類決定例項化物件的型別。
場景
假如我們開發專案中的日誌模組,業務初期只有控制檯日誌,大部分程式碼都在控制檯日誌類。隨著業務發展,希望可以增加檔案日誌功能。
如果程式碼之間已經存在耦合關係,此時向程式新增新類並不是一件簡單的事情。目前大部分程式碼都與控制檯日誌類有關。新增檔案日誌類需要修改全部程式碼,更可怕的是以後萬一要擴充其他日誌類,很可能需要再次大幅修改程式碼。
如此反覆反覆,恭喜成功誕生一份不可維護的祖傳程式碼。 ?
解決方案
工廠方法模式建議使用特殊的工廠方法代替直接呼叫 new 關鍵字建立物件。工廠方法返回的物件通常被稱作“產品”。
public abstract class Logger {
public abstract void log();
}
public class ConsoleLogger extends Logger {
@Override
public void log() {
System.out.println("我是控制檯日誌器!");
}
}
public class FileLogger extends Logger {
@Override
public void log() {
System.out.println("我是檔案日誌器!");
}
}
緊接著我們再建立一個工廠類,這裡宣告為抽象類,並且設定一個抽象方法,強制子類實現抽象方法。你也可以設定不設定成抽象類,在基礎工廠方法中返回預設型別。
public abstract class LoggerFactory {
public abstract Logger createLogger();
}
public class ConsoleLoggerFactory extends LoggerFactory {
@Override
public Logger createLogger() {
return new ConsoleLogger();
}
}
public class FileLoggerFactory extends LoggerFactory {
@Override
public Logger createLogger() {
return new FileLogger();
}
}
乍看之下,工廠方法模式看起來毫無意義,只是改變了程式中呼叫建構函式的位置而已。但是我們可以在子類裡重寫工廠方法,從而改變其建立產品的型別。
但有一點需要注意,僅當這些產品具有共同的父類或者介面時,工廠子類才能返回不同型別的產品。同時工廠基類的工廠方法還應將其返回型別宣告為共有介面。
只要產品類實現一個共同的介面,就可以將它傳遞給客戶程式碼,而無需提供任何額外的資料。
public class Application {
private final LoggerFactory loggerFactory;
public Application(LoggerFactory loggerFactory) {
this.loggerFactory = loggerFactory;
}
public void run() {
Logger logger = loggerFactory.createLogger();
logger.log();
}
}
客戶端程式碼僅通過抽象型別使用工廠和產品,如需要新增新的產品,僅需實現工廠抽象類和產品抽象類即可。無需修改原有的工廠或者產品類。
總結
這是重新學習單例模式的筆記,其中可能有很多地方寫的不對,寫得不好,歡迎大家指正 ?。
本作品採用《CC 協議》,轉載必須註明作者和本文連結