简单示例:
public class Food
{
public virtual void Eat()
{
StuffInMouth();
}
}
public class Fruit : Food
{
// Nothing here yet, but likely could be in the future
// Is this bad from a .NET/C# style guidelines perspective?
}
public class Apple : Fruit
{
public virtual void Eat()
{
Clean();
base.Eat();
}
}
public class Orange : Fruit
{
public virtual void Eat()
{
Peel();
base.Eat();
}
}
答案 0 :(得分:7)
尽可能简单,我称之为 Speculative Generality。
问题的原因:有时会创建代码"以防万一"支持从未实现的预期未来功能。结果,代码变得难以理解和支持。
Steve McConnell在Code Complete - 2中指出,
程序员在猜测某天可能需要哪些功能方面是出了名的。
<子> 的 1。要求尚不清楚,所以程序员必须猜测:错误的猜测意味着必须抛弃代码。
<子> 的 2。即使是近距离猜测细节仍然是错误的:这些复杂性将破坏程序员的假设 - 代码必须(或应该)丢弃。
<子> 第3。其他/未来的程序员可能会认为推测代码比它更好或更有必要:他们在推测代码的基础上构建代码,在必须删除或更改推测代码时增加成本。 子>
<子> 的 4。推测的普遍性增加了复杂性并需要更多的测试和维护:这会增加成本并减慢整个项目的速度。
致谢:代码完成 - 2 | Pluralsight course on refactoring
答案 1 :(得分:1)
Imho这是一个额外的抽象层,没有附加价值。 它增加了不必要的复杂性,所以在我看来这是不好的做法和YAGNI的一个例子。
答案 2 :(得分:1)
是的,重要的是要意识到虽然它可以节省时间来做这样的事情(如果它被使用),通常最好为不久的将来编码,或者至少了解你何时为未来编码永远不会来。
还有太早实施的维护开销。
答案 3 :(得分:1)
没有人说班级必须有任何成员。一个类表示一个对象的类别,所以如果它们没有有用的属性(不是语言的意思),那么将它清空是完全没问题的。因此,重要的是该类是否代表了代码需要使用的有意义的对象类别。
在您的情况下,如果您的代码通常以食物为食,那么共同的Food
祖先是有道理的。 然而,更好的概念可能是引入IFood
接口,有效地将食品合同与实际继承层次结构分离。例如,一个有意义的层次结构可以从Animal
类开始,但不是每个动物都被视为食物(免责声明:这是一个粗略的例子)。