2009-06-22 65 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最初描述了服务定位器模式,因此将它称为反模式是一件非常棘手的事情,但我知道我并不孤单。因人而异。