-1

首先,这严格来说是一个 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
        };
    }
}

虽然我猜任何一个“原型”实现都可以工作,但问题:我在我们的代码库中看到的方式有哪些含义(即第一个示例?)

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

4

3 回答 3

2

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

  • #1 为您提供类似于“实例单例”的东西......Someprototype从单个实例派生的所有 sFoo将是引用相等的。如果您从不更改它们,则可以很好地保留内存。
  • #2 为每个调用提供一个独立的实例。太好了,如果您需要修改它们。
于 2013-05-10T13:30:16.957 回答
1

含义非常简单:第一个实现将可能的“原型”转换为“单例”。正如您正确指出的那样,使用此类原型的所有内容都必须使用相同的实例。这是不可取的,因为实例是可变的。您拥有的表示通用 false 和 true 状态的两个对象将非常适合单例,但您应该使它们不可变,或者通过只读接口呈现它们:

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
    };
    ...
}
于 2013-05-10T13:29:18.313 回答
1

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

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

那么,有什么区别?

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

现在关于原型设计:

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

例子:

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
}

回到问题:你想使用什么模式?原型模式还是工厂模式?

于 2013-05-10T13:31:24.377 回答