2009-06-24 18 views
3

我不知道是否有這個官方名稱,但我一直在玩我喜歡稱之爲「自制」模式。基本上,這是抽象基類自身作爲工廠的時候。讓我解釋一下:「自制」模式

我在我的系統中有Foo對象和Bar對象,它們通過接口FooInterface和BarInterface使用。我需要爲我的客戶提供正確的Foo和Bar類型。決定創建哪個具體的Foo對象是在編譯時做出的。例如,如果你在win32上編譯,你只想創建Win32Foo對象,並且如果你在OSX上編譯,你只想創建OSXFoo對象等等。但是,決定創建哪個具體Bar對象是在運行時根據關鍵字串創建的。

現在,我的問題是關於實施此方案的最佳方式。一種方法我想出使用常規的工廠:

shared_ptr<FooInterface> foo = FooFactory::create(); 
shared_ptr<BarInterface> happyBar = BarFactory::create("Happy"); 
shared_ptr<BarInterface> sadBar = BarFactory::create("Sad"); 

另一種方法是用我稱之爲「自我工廠」:

shared_ptr<FooInterface> foo = FooInterface::create(); 
shared_ptr<BarInterface> happyBar = BarInterface::create("Happy"); 
shared_ptr<BarInterface> sadBar = BarInterface::create("Sad"); 

哪些優點和每種方法的利弊,無論是從一個可用性的立場,從建築的角度來看?

+0

我認爲你所建議的自制工廠也稱爲原型模式。您可能可以查看關於該模式的文獻以獲取想法。 – 2009-06-24 22:06:24

回答

2

工廠有兩個常見用途:

1)在運行時決定動態多態型的基礎上,參數和/或全局狀態(例如配置)。你的模式做到了。

2)依賴注入:而不是使用一個靜態函數來創建對象,使用工廠對象,使得對象的類型可以返回的由呼叫者進行配置,通過使在任何他們想要的工廠。這些模式都沒有提供這個。此外,你的第二個模式甚至不允許靜態依賴注入(通過使模板函數將工廠類作爲模板參數),因爲接口和工廠是相同的。

因此,您的模式(以及您的常規工廠)的一個con就是不支持依賴注入。有一個函數只有一個調用來獲取FooInterface的對象,那就是FooInterface :: create()。我不會爭辯爲什麼依賴注入是有用的,只是指出如果以這種方式構建,就不能使用它。

1

通常工廠負責創建整個類層次結構的對象。因此,在你的例子中,你將有一個Win32Factory,OSXFactory等。其中一個優點是你必須在工廠創建時選擇特定的實現(win32/unix/etc)一次 - 但是如果你使用類接口,你有一直提供OS信息。

如果您只有兩個類(Foo和Bar),我不確定是否值得爲它們創建工廠,而不是僅使用接口的create方法。

哦,並且當一個接口有一個創建它的類型的對象的方法時,它被稱爲factory method pattern

3

我會做的改進:

shared_ptr<FooInterface> foo = Factory<FooInterface>::create(); 
shared_ptr<BarInterface> happyBar = Factory<BarInterface>::create("Happy"); 
shared_ptr<BarInterface> sadBar = Factory<BarInterface>::create("Sad"); 

你會聲明:

template <class I> 
struct Factory { }; 

,然後爲需要一個工廠每個接口,你可以這樣做:

template <> 
struct Factory<FooInterface> 
{ 
    static FooInterface create(); 
}; 

這使您可以將工廠實現與接口聲明分開,但仍然使用類型系統bi在編譯時找到它們。