我有一个基类Base
需要创建另一个类型TRequired
的实例,但是,只有来自Base
的派生类知道如何构建它们。
使用抽象属性作为工厂方法是不好的风格? e.g。
protected abstract TRequired NewTRequired { get; }
我应该出于某种原因使用某种方法吗?有没有指导为什么我应该/不应该在这里使用房产?
答案 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)
属性设计用于“看起来像”字段的内容,例如对象的位置。
每次获得新实例时返回一个新实例的属性是非常差的设计。
您应该使用方法。