工厂方法实施的含义

时间:2013-05-10 13:22:15

标签: c# prototype

首先,这是一个严格的C#问题!请将您的知识限制在C#中。

在我正在开发的应用程序中,我们提供了一些我们为其提供预设“原型”的课程。处于非常高的水平:

public class Foo
{
    #region Variables / Properties

    public bool Bar { get; set; }
    public string Name { get; set; }
    public int Fooby { get; set; }

    #endregion Variables / Properties

    #region Prototypes

    public Foo SomePrototype = new Foo
    {
        Bar = false,
        Name = "Generic False State",
        Fooby = -1
    };

    public Foo SomeOtherPrototype = new Foo
    {
        Bar = true,
        Name = "Generic True State",
        Fooby = Int32.MaxValue
    };

    #endregion Prototypes

    #region Methods

    // ...Behaviors here.

    #endregion Methods
}

请注意“原型”部分。我一直都知道在C#中,做“这种'原型'的'正确'方法是:

public Foo SomePrototype
{
    get 
    { 
        return new Foo
        {
            Bar = false,
            Name = "Generic False State",
            Fooby = -1
        };
    }
}

虽然我猜这两种“原型”实现都可行,但问题:我在代码库中看到的方式有什么影响(即第一个例子?)< / p>

对我来说,显而易见的含义是,“原型”的所有用法都只是对面向公众的Foo变量的引用,它可以提供一些有趣的交互......我只是想知道是否有更需要注意的。

3 个答案:

答案 0 :(得分:2)

这两段代码并不是同一件事的不同实现,而是服务于不同的目的:

  • #1为您提供类似“实例单例”的内容......从Someprototype的单个实例派生的所有Foo将是引用相等的。如果你永远不改变它们,那么很好地保存记忆。
  • #2为每次通话提供一个独立的实例。很好,如果你需要修改它们。

答案 1 :(得分:1)

含义非常简单:第一个实现将可能的“原型”转换为“单例”。正如您所正确指出的那样,使用此类原型的所有内容都必须使用相同的实例。这是不可取的,因为实例是可变的。你表示一般的假和真状态的两个对象对单身人士来说是非常好的候选者,但是你应该让它们成为不可变的,或者通过只读接口呈现它们:

interface IFoo {
    bool Bar { get; }
    string Name { get; }
    int Fooby { get; }
}
public class Foo : IFoo {
    ...
    public static readonly IFoo SomePrototype = new Foo
    {
        Bar = false,
        Name = "Generic False State",
        Fooby = -1
    };

    public static readonly IFoo SomeOtherPrototype = new Foo
    {
        Bar = true,
        Name = "Generic True State",
        Fooby = Int32.MaxValue
    };
    ...
}

答案 2 :(得分:1)

在您的示例中,存在一些差异(从技术角度看,与原型设计无关,但与C#无关):

  • 示例1:使用一次创建实例的公共可写字段。
  • 示例2:使用公共只读属性和每次调用创建的实例。

嗯,有什么区别?

  • Foo不是一成不变的。因此,程序可以在代码中的多个位置修改原型。在示例1的情况下,这将修改所有其他代码使用的原型(foo.SomePrototype.Fooby = -1),这可能是不合需要的。
  • 公共字段是可写的,因此程序可以修改对原型(foo.SomePrototype = new Foo {...})的引用,这对使用该原型的其他代码有影响。突然,原型可能会被取代。

现在关于原型设计:

  • 如果你看一下原型模式(http://en.wikipedia.org/wiki/Prototype_pattern),它只是说原型应该被用来创建它的新克隆。
  • 阅读该文章,您可以看到客户端负责创建克隆,而不是类本身。拥有原型意味着您拥有一个实例并创建它的许多副本。您的属性每次调用都会创建新实例。
  • 实际上您正在使用工厂方法模式。嗯...好吧,它是一个属性,但每次调用它时它仍会创建一个对象。
  • 在我看来,我会选择一个属性,每次调用都返回相同的引用。引用存储在私有(非公共)字段中。这种参考方式永远不会改变。

示例:

public class Foo  
{  
    #region Variables / Properties

    public bool Bar { get; set; }
    public string Name { get; set; }
    public int Fooby { get; set; }

    #endregion Variables / Properties

    #region Prototypes

    static private Foo _SomePrototype = new Foo
    {
        Bar = false,
        Name = "Generic False State",
        Fooby = -1
    };

    static private Foo _SomeOtherPrototype = new Foo
    {
        Bar = true,
        Name = "Generic True State",
        Fooby = Int32.MaxValue
    };

    static public Foo SomePrototype 
    {
        get
        {
            return _SomePrototype;
        }
    }

    static public Foo SomeOtherPrototype 
    {
        get
        {
            return _SomeOtherPrototype;
        }
    }
    #endregion
}

要反弹这个问题:你想用什么样的模式?原型模式还是工厂模式?