概要 之前讨論過行為型模式之一的Template method模式,而Factory method模式其實是Template method模式在Factory場景(建立對象)下的一種應用形式。對Template method模式的定義是 在基類中為算法架構定義方法,通過該方法去調用子類中封裝的算法各個步驟的具體實作,那麼Factory method模式呢?其實就是一種具體的應用,我對它的定義是,在基類工廠中定義對象建立的總體架構邏輯,子類工廠中實作具體對象建立的步驟,然後通過基類方法去調用子類中封裝的實際建立步驟。
目的 使用者可以忽略對象具體執行個體化的邏輯過程,通過調用統一的接口來進行對象執行個體化,同時解除調用方與具體對象間的耦合,使調用者隻依賴于抽象。(所有Factory模式的目的應該都一樣)
執行個體 Factory method模式最基本的實作,如下:
class AbstractObject {};
class ConcreteObjectA : public AbstractObject {};
class ConcreteObjectB : public AbstractObject {};
class ConcreteObjectNULL : public AbstractObject {};
class Factory {
public:
virtual AbstractObject* do_create() = 0;
AbstractObject* create_object() {
return this->do_create();
}
};
class FactoryA :public Factory{
public:
virtual AbstractObject* do_create() {
return new ConcreteObjectA;
}
};
class FactoryB :public Factory{
public:
virtual AbstractObject* do_create() {
return new ConcreteObjectB;
}
};
各個子類重寫do_create方法來負責具體對象的建立,基類提供方法do_create方法來作為統一的對象建立接口。具體使用如下:
Factory* factory = new FactoryA;
AbstractObject* obj = factory->create_object(); // 獲得ConcreteObjectA對象
看到這裡,也許有人會問,這樣做有什麼實際的意義嗎?不是把簡單問題複雜化了嗎?如果代碼真的隻是這樣的話,确實是過于複雜化了。但是現實問題往往不是這麼簡單的,會有很多額外的需求。比如,我們假設所有對象具體有initialize方法,在對象建立同時需要保證initialize方法被調用來進行正常的初始化,又比如可能我們需要對ConcreteObjectA建立時添加額外的邏輯判斷,等等等等,不同的對象建立初始化過程會接踵而至。基于上面的實作,我們簡單擴充下就可以滿足需求:
class AbstractObject {
public:
virtual void initialize() {}
};
class Factory {
public:
virtual AbstractObject* do_create() = 0;
AbstractObject* create_object() {
AbstractObject* obj = this->do_create();
obj->initialize();
return obj;
}
};
class FactoryA :public Factory{
public:
virtual AbstractObject* do_create() {
bool isOk = true;
// isOk = ...any judgement
if (isOk)
return new ConcreteObjectA;
return new ConcreteObjectNULL;
}
};
而可以稍微想象一下,如果我們把所有建立邏輯都耦合在一個Factory類中時,會給以後的擴充帶來很多麻煩。
應用 可以看出,Factory method是Template method模式的一種特例或一種應用方式。關于Template method模式請參考: