静态工厂方法与工厂

时间:2011-05-03 14:58:19

标签: .net design-patterns architecture factory-pattern

我的类应具有私有setter(或私有字段和与之关联的Readonly属性)的属性。如果我在这些类中有静态工厂方法来创建实例,那就没问题。然而,许多开发人员写道“静态工厂方法是建筑黑洞”,因为不可能继承静态方法。

C#没有友好的课程,因此我不能使用工厂。

您如何看待使用静态工厂方法?

6 个答案:

答案 0 :(得分:2)

类的所有只读依赖项应该由此类型的构造函数注入。这使代码更易于理解,调试,最重要的是,可以进行测试。因此,如果不可能,应该考虑您的类层次结构。如果您仔细遵循此原则,您还可以使用依赖注入框架在运行时解决此依赖关系。

样品:

class Foo : IFoo
{
    private readonly IBar bar;
    private readonly IBaz baz;

    public Foo(IBar bar, IBaz baz)
    {
        this.bar = bar;
        this.baz = baz;
    }

    // Readonly properties for bar and baz, if needed.
} 

答案 1 :(得分:2)

默认情况下,我会通过将所需的参数传递给构造函数来创建实例。如果构造函数包含许多参数,则您需要parameter object或违反SRP。如果根据参数有多种创建实例的选择,并且逻辑IS并不比静态工厂方法复杂,这可能是将创建逻辑保留在类中的最佳方法。

如果您有复杂的实例创建依赖于参数的规则以及可能使用工厂的其他因素,可能是一个流畅的工厂,它收集所有必需的参数,执行所需的逻辑,然后使用类公共构造函数创建物体。

答案 2 :(得分:1)

我不认为声明:

  

C#没有友好课程,   因此我无法使用工厂

来做到这一点

确实如此。

关键是不要在执行实现的类上创建静态工厂方法。你不会逃避强耦合。

您可能希望研究依赖注入/反转。您无需担心创建工厂,而是通过/ code config设置对象的创建方式; DI框架为您提供工厂,以及连接您指示所需的任何依赖项。

答案 3 :(得分:1)

你必须以这种或那种方式制造这个“黑洞”。您可以使用构造函数,这更容易。但是,我发现静态方法更好。它们几乎共享构造函数的所有体系结构属性,除了稍微好一些,因为构造函数必须始终创建一个新实例,因此构造函数无法实现某些实现抽象。

所以,答案是:请使用静态方法! :)

答案 4 :(得分:1)

我相信当人们说静态工厂方法“......是一个建筑黑洞”时,他们指的是扩展工厂方法的问题。判断点是创建的类有多复杂。如果它们是重量级的,那么从长远来看,可能静态的工厂方法会弄得一团糟。

C#确实有“内部”修饰符,对于朋友而言,它不是替代其他人在你的班级上工作,但重要的是你能够在未来扩展工厂而不是其他人,可以将工厂打包并创建类作为单独的程序集,因此使用“内部”,如“朋友”。

而且,是的,这是使用C#的问题。冲突的要求放弃了对旧友好工厂阶级的支持,这很痛苦。如果您不能使用“internal”,并且您的工厂正在渲染重量级类,那么实际上没有任何替代方法可以向类中添加“InitInstance()”类型方法,因此可以扩展“制造过程”。

答案 5 :(得分:0)

如果目标和工厂不在同一个程序集中,那么获取写入方法的部分封装的一种方法是使用私有接口实现,而不使用客户端代码。

internal interface IMyClassFactorable
{
    string MyProperty{ set; }
}

public class MyClass : IMyClassFactorable
{
     private string _myProperty;
     public string MyPrperty { get { return _myProperty; } }
     string IFactoryable.MyProperty { set { _myProperty = value; } }
}

如果工厂和目标位于同一个程序集中,则使用内部setter

public class MyClass 
{
     public string MyPrperty { get; internal set; }
}