設計模式-建立型-工廠方法

icecho發表於2020-11-06

介紹

工廠方法是一種建立型設計模式,其在父類中提供一個建立物件的方法,允許子類決定例項化物件的型別。

場景

假如我們開發專案中的日誌模組,業務初期只有控制檯日誌,大部分程式碼都在控制檯日誌類。隨著業務發展,希望可以增加檔案日誌功能。

如果程式碼之間已經存在耦合關係,此時向程式新增新類並不是一件簡單的事情。目前大部分程式碼都與控制檯日誌類有關。新增檔案日誌類需要修改全部程式碼,更可怕的是以後萬一要擴充其他日誌類,很可能需要再次大幅修改程式碼。

如此反覆反覆,恭喜成功誕生一份不可維護的祖傳程式碼。 ?

解決方案

工廠方法模式建議使用特殊的工廠方法代替直接呼叫 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 協議》,轉載必須註明作者和本文連結
Hello。

相關文章