工厂与实例构造函数

Nei*_*l N 39 c# oop constructor coding-style

我想不出为什么一个比另一个更好的原因.比较这两个实现:

public class MyClass
{
    public MyClass(string fileName)
    {
        // some code...
    }
}
Run Code Online (Sandbox Code Playgroud)

而不是:

public class MyClass
{
    private MyClass(){}

    public static MyClass Create(string fileName)
    {
       // some code...
    }
}
Run Code Online (Sandbox Code Playgroud)

.Net框架中有一些地方使用静态方法来创建实例.起初我在考虑,它注册它的实例来跟踪它们,但是常规构造函数可以通过使用私有静态变量来做同样的事情.

这种风格背后的原因是什么?

Ada*_*son 51

注意:你拥有的不是静态构造函数,它是一个静态函数,它创建实例而不是自己调用实例构造函数.静态构造函数完全是另一回事.

工厂模式是使用函数(静态或非静态)实例化类型而不是直接使用构造函数的典型示例.需要注意的是实际的实例构造函数将获得无论什么所谓,但静态功能提供间接层,允许其返回任何类型,要么是或返回类型继承的实例,而不是只实例返回类型.

例如:

public abstract class BaseClass
{
    public static BaseClass Create(int parameter)
    {
        if (parameter == 1)
        {
            return new Class1();
        }
        else
        {
            return new Class2();
        }
    }
}

internal class Class1 : BaseClass
{
    //code here ...
}

internal class Class2 : BaseClass
{
    //code here ...
}
Run Code Online (Sandbox Code Playgroud)

这允许您隐藏Class1Class2从外部程序集隐藏,同时仍然允许消费者处理专门的事情.

  • @Nathan:是的,虽然我很确定他的代码是*示例*而不是实际的代码片段(因此`// some code ...`blocks). (10认同)

Dan*_*plo 19

我正在研究这个问题并遇到了这个问题,但并不觉得它得到了充分的回答.但是,我确实找到了这篇方便的文章 - 设计指南更新:工厂与构造函数 - 由Krzysztof Cwalina(.NET Framework上的首席架构师).值得一读整篇文章,但这里有一些要点的简要概述:

创建类型实例的最常见且一致的方法是通过其构造函数.但是,有时候更好的选择是使用Factory模式.

比工厂更喜欢施工人员,因为他们通常比专业建筑机制更加一致和方便.

将Factory操作实现为方法,而不是属性.

返回实例作为方法返回值,而不是out参数.

如果您需要更多地控制实例的创建模式,请考虑使用Factory.

考虑通过连接"Create"和正在创建的类型的名称来命名Factory方法.

考虑通过连接正在创建的类型的名称和"Factory"来命名工厂类型.

如果构造操作必须可供子类专门化,则不要使用静态方法实现Factory.

使用Factory进行转换样式操作.

如果操作需要感觉不自然的参数信息传递给构造函数,请使用Factory.

在创建操作将用作实例化类型的核心方案的情况下,请勿使用Factory.在这些情况下,可发现性和一致性是至关重要的.

考虑使用构造函数而不是Factory.只有在这个思考过程之后才能继续实施工厂.

工厂通常也很方便通过多态实现类型专业化.

如果API用户将编码到其实现可能随时间变化的基类或接口,请使用工厂.

在开发人员可能不知道要构造哪种类型的情况下,例如在对基本类型或接口进行编码时,请使用Factory方法.

如果必须支持多态扩展,请将Factory操作实现为虚拟实例方法而不是静态方法.

对基于实例的工厂使用Singleton模式,以便强制开发人员只是为了调用其中一个成员来实例化Factory类型.

如果构造函数不足以描述正在执行的操作,请使用Factory方法,并且从单独命名的Factory获得的附加信息使操作的目的更加清晰.


naw*_*fal 10

工厂方法帮助的另一种常见情况(在C#等语言中不支持构造函数的类型推断)是必须最小化类型参数规范.考虑Tuple类的常见情况.你可以这样做:

new Tuple<int, int>(1, 1); //constructor call
Run Code Online (Sandbox Code Playgroud)

要么

Tuple.Create(1, 1); //factory pattern.
Run Code Online (Sandbox Code Playgroud)


Chr*_*isW 7

静态Create方法可以实例化并返回:

  • 一个MyClass实例
  • 任何子的实例MyClass
  • null

  • 轻微附录:在前两种情况中的任何一种情况下,返回的对象可能是新创建的对象实例或共享对象实例.如果其他代码检查引用相等性,则区别可能很重要. (6认同)