收集命令对象的名称

use*_*702 1 java oop naming-conventions

我正在开发命令处理程序,其中每个命令可以无限地包含子命令。所有命令都由“ CommandManager”在根级别进行管理,该命令管理器采用用户输入解析选项,然后找到正确的命令并将输入传递给它。由于CommandManager和Command都具有类似的获取和存储指定命令的方式,并且由于这两个类都非常混乱,因此我想将查找和存储命令的逻辑分解为一个通用的超类,但是,我不认为描述性名称的名称。

我之所以尝试使CommandMagager和Command都扩展另一个类的原因是,命令管理器在根级别上的行为类似于命令。命令实际上不包含任何处理命令的逻辑,它们只是提供一种注册和检索具有特定名称的命令的方法。

是否有任何常规约定可以帮助我找到名称,或者这是解决问题的错误方法?

Chr*_*jer 5

是的,对此有一些规则,没有一成不变的做法,只是一种经验和模仿使它们成为公认的最佳实践。

总览

  • 明确责任。
  • 使用骆驼套。
  • 命名对象,而不是类。
  • 使用名词。
  • 避免的话喜欢InfoProcessorManager
  • 如果有对象,请使用单数形式。
  • 对实用程序类使用复数形式。
  • 前缀抽象基类Abstract
  • 后缀为的隐藏实现类Impl
  • 不要在interface名称前加上I
  • 正确使用设计模式名称。
  • 前缀名称及其专业名称。
  • 正确使用数据结构名称

细节

明确责任

重要的是,名称应能很好地反映出责任。名称应传达其意图。

名称对象,而不是类

使用单个对象时看起来不错的名称。命名对象,而不是类。

使用骆驼盒

UseCamelCaseForNamesOfTypesInJava。

使用名词

为对象使用名词。如果对象表示动作,则将动词转换为名词。如果对象表示属性,则将形容词变成名词。例如,如果动作为compile()Compiler则如果它是主动动作,或者Compilable是被动技能,则使用。如果该动作为run()Runner则为主动动作,Runnable如果为被动技能则使用。

避免的话喜欢InfoProcessorManager

在大多数情况下,它们只是“我不知道该怎么称呼”(Robert C. Martin)的同义词。这本身就是“我不知道这件事在做什么”或“这件事在做一件以上的事情”的症状。这就是为什么当我们看到这样的名字时,我们经常正确地感到有重构的渴望。

如果有对象,请使用单数形式

类名通常是单数,特别是如果您可以获得单个类的多个对象。我们喜欢为此类对象的集合的变量名称保留复数形式。

好例子

JButton button;
List<JButton> buttons;
Run Code Online (Sandbox Code Playgroud)

不好的例子

Properties是坏的类名,因为尽管有对象,但它是复数。我们喜欢叫List<JButton> jButtons。因此,您如何称呼List<Properties>- propertiesspropertiesespropertiessies???

对实用程序类使用复数

如果一个类仅包含仅出于为另一种类型提供实用程序方法而存在的静态方法,则该类为实用程序类。

好榜样

CollectionsSpilteratorsArraysExecutorsFileSystemsFilesPaths

前缀抽象基类 Abstract

接口的抽象基础实现Foo通常称为AbstractFoo

例如:AbstractActionAbstractListAbstractMapAbstractQueue等等。

确保此名称是用户几乎看不到的AbstractSomething名称,对于实现者/扩展者而不是用户而言,这是一个很好的名称。并且仅在没有更好的名称的情况下选择此名称。

后缀隐藏的实现类 Impl

为接口或抽象类提供默认实现的类Foo有时被称为FooImpl

确保用户永远不会看到此名称。永远不能。这仅对实现者有益,没有其他人。用户之类的名称XyzImpl必须是不可见的。并且仅在没有更好的名称的情况下选择此名称。

不要在interface名称前加上前缀I

OO语言中类型的目的通常是封装和隐藏事物。类型是a class,an interface,an enum还是@interface批注都是该类型的详细信息。在两种情况下,您需要了解有关类型的这些详细信息:要扩展类型时以及要创建该类型的对象时。这些用例是类型的用例的少数。通过给接口名称加上前缀I,可以大声地声明实际上应该隐藏的实现细节,从而违反了该原理。

将s 放在s I的名称之前interface就像使用匈牙利表示法。仅当您在必须跟踪类型的这些物理方面的环境中工作时,匈牙利符号才有意义。(因此,这几天在C语言中甚至都没有必要!)

此外,当你不想看起来像个白痴

  • 您决定更改接口中的类,反之亦然,并且不重命名类型,最终会得到一个不带I-prefix 的接口或一个带I-prefix 的类。
  • 您决定更改界面中的类,反之亦然,然后重命名该类型,最终会惹恼用户。
  • 甲骨文删除之间的差异class,并interface在Java中的未来版本(不是那么不可能的,看看如何接口有静态和默认方法现在)。
  • 您将API移植到另一种不区分class和的语言,interface并且现在有了带有I前缀的类或具有不同名称的类。

正确使用设计模式名称

如果使用设计模式,则可以使用它的名称(如果合适)。但是,如果您不使用设计模式,请避免使用设计模式的名称。

在使用设计模式时,可以选择使用设计模式名称-如果有助于或通常使用设计模式的名称,请使用它,例如Factory,抽象工厂的-suffix。

但是,当您实际上不使用设计模式名称时,几乎必须避免使用它。如果命名某项Command但没有实现命令模式,命名Strategy但却未实现战略模式,如果命名某事Factory但没有实现Factory模式,可能会造成混淆。

这并不总是令人困惑,可能需要做出一些判断。例如,您可能有一个框架来编写带有界面的命令行程序以及这些命令行程序的抽象基类。您可能要调用它们CommandAbstractCommand尽管事实上这并不是Command设计模式,至少从语言本身的角度来看并非如此。

使用名称的示例

  • KeyFactory 工厂设计模式
  • DocumentBuilder 生成器设计模式
  • Action 命令设计模式(又名ActionTransaction

不使用名称的示例

  • RunnableCallable- 命令设计模式,但名称不同,但更专业。
  • Collections.synchronizedList()- 工厂方法装饰

前缀名称及其专业化

当我们在继承树中向下移动时,类名通常会增长,方法是在基类的名称前加上有关专业化的信息。

例子

  • ListAbstractListArrayListAbstractSequentialListLinkedList
  • SetAbstractSetHashSetLinkedHashSet

正确使用数据结构名称

如果实现数据结构,请使用适当的名称。

具有键/值对而不管其如何维护的概念称为字典,因此描述该键/值对的接口应命名为Dictionary。(Java之所以将其命名为Map的原因是Java 1.0中的原始集合是纯设计的,并且已经使用了抽象类Dictionary,因此interface需要一个新名称。)

你的情况

在您的情况下,我可以想象以下设计:

  • interface Command { void execute(); } 对于可以执行的一切。
  • interface CommandQueue { void submit(Command); } 可以提交命令的东西。
  • interface CommandRunner extends CommandQueue { void start(); void stop(); }

如果您提供更多详细信息,我可以更新此部分。对于排队和处理命令的内容,您可能还需要考虑并行化并进行研究java.util.concurrent