工厂方法实现的含义
本文关键字:实现 方法 工厂 | 更新日期: 2023-09-27 18:12:56
首先,这是一个严格的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
变量的引用,这可以提供一些有趣的交互……我只是想知道是否还有更多需要注意的
这两段代码并不是同一件事的不同实现,而是服务于不同的目的:
- #1给出了类似于"实例单例"的东西…从单个
Foo
实例导出的所有Someprototype
都是参考相等的。如果您从不更改内存,那么保存内存非常好。 - #2为每个调用提供一个独立的实例。很好,如果你需要修改它们。
在你的例子中有一些不同之处(从技术角度来看,这与原型设计无关,但与c#有关):
- 示例1:使用一次创建实例的公共可写字段。
- 示例2:使用公共只读属性,每次调用创建一个实例。
那么,有什么不同呢?
-
Foo
不是不可变的。因此程序可以在代码中的多个位置修改原型。在示例1的情况下,这会修改所有其他代码使用的原型(foo.SomePrototype.Fooby = -1
),这可能是不希望的。 public字段是可写的,因此程序可以修改对原型(
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
}
要回答这个问题:你想用什么模式?是样板还是工厂样板?
含义非常直接:第一个实现将潜在的"原型"转换为"单例"。正如您正确指出的那样,使用这种原型的所有东西都必须使用相同的实例。这是不可取的,因为实例是可变的。表示一般的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
};
...
}