[Note]Creational-Factory

什麼是Factory(工廠)呢?

定義:建立一個接口,讓子類自己決定實現哪一個Factory,其重點是繼承了Simple Factory Patterns的優點,同時解決了它的問題

簡單例子

注: 以下程式單純用於解釋,並不能實際執行

可透過子類繼承Factory的抽象類自主決定生產什麼樣的Product。  
生產的Product在透過里氏替換原則(Lisko Subsititution princeple)替換成繼承與Logger的子類,即可換成的需要的Logger。
class Logger{
    public:
    	virtual void wirteLog() = 0;
}

//Implement
class DatabaseLogger: public Logger{
    pubic:
    	void wirteLog(){
            //Wirte DB log message
        }
}

class FileLogger : public Logger{
    public:
    	void wirteLog(){
            //Write File Log message
        }
}

//Abstruct Factory
class Factory{
    public:
    	virtual Logger* createLogger() = 0;
}
//不可以是Static靜態,因為子類是動態實現父類的函數(static 沒有this指標)
//Implement
class FileLoggerFactory : public Factory{
    public:
    	Logger* createLogger(){
            //init file logger 
            //TODO init etc

            //create file logger
            Logger* logger = new FileLogger();
            //TODO Create file etc

            return Logger;
        }
}

class DabatabaseFactory : public Factory{
    public:
        Logger* createLogger(){
           	//Connect to db
            //Create db logger etc...
            Logger* logger = new DatabaseLogger();
            //init this logger etc...
            return logger
        }
}

//Client to use
int main(){
    Factory *factory = new FileLoggerFactory();
    Logger *logger = factory->createLogger(); //return the Product that it is initialized
    Logger->wirteLog();
    return;

    //如果想讓系統有更多靈活性和課擴展性,可以透過xml來進行配置,不需透過修過client的代碼
    //只需更新xml中的設置,在代碼中新增新的Product 以及新增的Factory 並重新編譯便可

    //除了默認的設置方法外,還想透過傳入String的方法來自定義設計,例如連接要DB,文件的路徑等等
    //可以透過Override Abstruct class 的func來進行設置
    /*
    	class Factory{
            public:
            	virtual Logger* createLogger() = 0;
            	virtual Logger* createLogger(string config) = 0;
            	virtual Logger* createLogger(Object obj) = 0;//通過Obj裡面的成員進行設置等
		}
    */
}

優點

  • Client無需知道Object的設置的細節,也無需知道實質Object的名稱,只需通過工廠即可
  • 工廠(Factory)以及產品(Product)都是透過Polymorphism(多態)來實現,也是工廠模式的關鍵,工廠可以自主的決定要生產什麼產品,在內部進行設置產品(封裝在內部)
  • 加入新的Product時無需修改Abstract class 以及 具體的工廠和產品的類,只要擴展新增即可,符合Open-Close principle
  • 透過繼承抽象類使系統更容易擴展

缺點

  • 新增產品時,要加入新的產品類以及工廠類,增加了系統的複雜度,而且需要從新編譯,增加了開銷
  • 為了擴展性,加入了抽象類,Client都使用Abstract class 進行編程,增加了系統的抽象性和理解難度

參考資料:
史上最全设计模式导学目录(完整版)