确保所有抽象类的名称都以“抽象”为前缀是一种好习惯吗?
9 回答
你可以,但我倾向于不这样做,因为它是一个实现细节。
我不喜欢在类型和标识符的名称中添加实现详细信息,因为这种信息将来可能会发生变化。在我看来,最好将事物命名为它们是什么,而不是它们碰巧是如何实现的。
我认为这个命名约定只是使用,因为很难想出另一个好名字。如果您已经有一个名为“List”的接口,那么如何命名“AbstractList”类?更多的是避免名称冲突,然后告诉实现细节。
这取决于您的编码约定。
如果您还没有接口 Foo,您也可以将它们称为 FooBase,或者仅称为 Foo。
如果您考虑它在 .NET 框架中的情况,则不会。以抽象 Stream 类为例。类名中没有任何内容表明它实际上是抽象的。
有点难以解释,但我只使用它来避免在功能类中复制/粘贴相同的代码,而不是在域对象之类的东西中。
- AbstractServiceTestCase --> Abstract 前缀似乎很有帮助
- AbstractAnimal --> 看起来很奇怪而且没有帮助
你当然应该自己决定,只要在整个项目中遵循相同的约定。
由于以下原因,我不会将抽象类称为 Abstract:
每个Rectangle都是一个Shape。在任何可以使用形状的地方,都可以使用矩形。处理 Rectangle(但也可以处理 Circles)的代码可能如下所示:
Shape s = .....;
s.drawTo(myGraphicsContext);
在任何可以使用它的一般化(例如形状)的地方使用对象(例如矩形)是面向对象概念的重要组成部分,被称为里氏替换原则。(这也很明显:什么样的句子或逻辑会陈述形状,但不适用于矩形?)
如果您将泛化命名为AbstractShape,则违反了此原则。矩形不是 AbstractShape。如果有的话,那就是“具体形状”!矩形不是抽象的(在“我不知道这是什么类型的形状。可以是矩形,也可以是其他任何东西。”)。然后使用 AbstractShape 的代码读取错误:
AbstractShape s = new Rectangle(...);
我在这里写了关于这个主题的更多想法。
我发现以这种方式命名类很有用。它发送一条消息,表明它们打算被子分类;未实例化;包含子类共有的代码等。
但这并不总是必要的。大多数程序员可能会将“Shape”识别为抽象类,将“Square”、“Circle”等识别为具体类。但如果不是立即清楚,这是一个有用的提示。
您还应该遵循本地编程约定和样式指南。
我认为这部分取决于您将如何使用该课程。如果它仅用于内部使用以强制派生类符合接口,那么在它之前添加 Abstract 可能不是一个坏主意。但是,如果您提供的 Foo 工厂将提供实际上是 SpecializedFoo1 或 SpecializedFoo2 的 Foo 实例,那么返回 AbstractFoo 实例似乎很尴尬。
到目前为止的答案非常有帮助,并显示了负责任的实践传播。我倾向于同意名称不应该表示实现(Foo
可能是后来移动到接口的抽象类)。但是,在编码时获得需要为派生类提供方法的视觉线索对我很有用。
例如,我目前有一个层次结构(不要询问名称的基本原理,但它们在上下文中是有意义的并映射到 XML 元素名称)。我正在使用 Java,但我认为大多数语言都是相似的:
public abstract class Marker {...}
public class Template extends Marker {...}
public class Regex extends Marker {...}
我现在倾向于:
public abstract class Marker {...}
public class TemplateMarker extends Marker {...}
public class RegexMarker extends Marker {...}
而不是
public abstract class AbstractMarker {...}
public class Template extends AbstractMarker {...}
public class Regex extends AbstractMarker {...}
或者
public abstract class AbstractMarker {...}
public class TemplateMarker extends AbstractMarker {...}
public class RegexMarker extends AbstractMarker {...}
我个人可以记住这Marker
是一个抽象的功能概念,子类是具体的实现。