使用属性作为工厂方法

时间:2013-07-15 22:01:14

标签: c# properties factory-method

我有一个基类Base需要创建另一个类型TRequired的实例,但是,只有来自Base的派生类知道如何构建它们。

使用抽象属性作为工厂方法是不好的风格? e.g。

protected abstract TRequired NewTRequired { get; }

我应该出于某种原因使用某种方法吗?有没有指导为什么我应该/不应该在这里使用房产?

3 个答案:

答案 0 :(得分:8)

你应该肯定使用方法,因为访问此成员 某事。调用方法是让代码在这方面说话的好方法。

或者,如果您更喜欢另一个视角:该成员的两次后续访问将返回不同的结果。一个好的经验法则是在这种情况下使用方法,以免违反principle of least astonishment

这看起来它正在读取变量的结果,即使你知道NewTRequired是属性(而不是字段),你也知道它实际上是在运行任意代码:

var prototype = Factory.NewTRequired;

我故意将结果放入一个名为prototype的变量中,以便更好地表明即使是知情的读者也可以轻易地抛弃这段代码:看到这一点并认为“正确,这是不合理的所以NewTRequired是X“的原型对象。那个读者肯定会对这样的代码结果感到惊讶:

var eq = object.ReferenceEquals(prototype, Factory.NewTRequired);

将此与工厂方法进行对比。现在这段代码可能会散发出轻微的气味:

// hmmm... are we actually using this as a prototype?
// because it sure looks like an instance created just for the occasion.
var prototype = Factory.NewTRequired();

这段代码永远不会让你大吃一惊:

// obviously should be false, the code screams "I am creating new instances!"
var eq = object.ReferenceEquals(Factory.NewTRequired(), Factory.NewTRequired());

这个规则真正should have been followed but was not属于DateTime.Now属性的着名示例。

答案 1 :(得分:5)

我建议使用一种方法:

protected abstract TRequired CreateRequired();

创造意味着“工作”的发生。这更适合方法与属性,因为属性获取器意味着通常会快速返回而不执行大量代码。

即使您的问题标题“属性为工厂方法”也意味着工厂方法应该是方法

答案 2 :(得分:4)

属性设计用于“看起来像”字段的内容,例如对象的位置。

每次获得新实例时返回一个新实例的属性是非常差的设计。

您应该使用方法。