2009-06-22 78 views
2

說我已經有一個靜態的工廠方法,像這樣一類:內部工廠的靜態工廠方法網關 - 代碼異味?

public class Table 
{ 
    public static Table OpenTable(string path) 
    { 
     ITableFactory fac = IoC.Resolve<ITableFactory>(); 
     return fac.OpenTable(path); 
    } 
} 

和工廠類,看起來像這樣:

internal class TableFactory : ITableFactory 
{ 
    internal Table OpenTable(string path) 
    { 
     //Check the path 
     //Do some other stuff 
     //return a new Table. 
    } 
} 

這段代碼臭到你?

編輯:另一個問題:是否有一個靜態方法的類型只是轉發調用工廠是一個好主意?

一些背景資料:我曾經有過TableFactory公共和使用戶創建一個新的每次他們需要打開一個表格的時間,但感覺就像一個很長的大廳只開一臺。所以我認爲我會在Table類上創建一個靜態工廠方法,並使工廠類成爲內部類,並使用IoC來解決它。

回答

3

我認爲這不好,本身,但也許有點不尋常。

但是,我會將表工廠作爲單獨的對象呈現給用戶,並使用它來創建表。爲什麼?這更傳統一點,它使您能夠提前配置工廠,並將其用於創建多個表格,例如

TableFactory tf = new TableFactory(); 
tf.setWhatever(); 
tf.setWhatever2(); 
// ...etc... 

// now create your tables based on the above. 

您的代碼,不需要(一定)瞭解創建表的東西,不是事實,其他的是它被賦予了TableFactory(內置和其他配置)

這可能是矯枉過正,你在做什麼這樣做。但我發現這是一種有用的模式。

0

看起來很好。然而,我會移動fac:

public class Table 
{ 
    private static readonly ITableFactory fac = IoC.Resolve<ITableFactory>(); 
    public static Table OpenTable(string path) 
    { 
     return fac.OpenTable(path); 
    } 
} 
+2

這將是一個小小的問題,如果您決定在第一次調用OpenTable之後的某段時間在運行時切換依賴關係。因爲它沒有靜態的構造函數,所以它也可能不會確定性地存在instantiate fac。 – 2009-06-22 10:14:14

0

我不認爲這太糟糕......它只是一個快捷方法,沒有引入新的依賴關係。

我知道你可能做Kernel.Get<Table>(path)並避免所有這些雜耍。

0

據我所知,你在這裏有什麼是Service Locator模式的一個實例,因爲我認爲IoC是一個類型名稱,而Resolve是IoC類型的靜態方法。不管你的TableFactory是否是內部的,都不那麼關心。

我認爲服務定位器是一種反模式,因爲它對API的用戶來說是完全不透明的,這種依賴關係需要到位;因此,我們可以在調用IoC.Resolve的上下文中輕鬆地調用Table.OpenTable,並且API絕對不會提供這種情況。您也沒有編譯時檢查。

我知道Martin Fowler最初描述了服務定位器模式,因此將它稱爲反模式是一件非常棘手的事情,但我知道我並不孤單。因人而異。