我正在开发命令处理程序,其中每个命令可以无限地包含子命令。所有命令都由“ CommandManager”在根级别进行管理,该命令管理器采用用户输入解析选项,然后找到正确的命令并将输入传递给它。由于CommandManager和Command都具有类似的获取和存储指定命令的方式,并且由于这两个类都非常混乱,因此我想将查找和存储命令的逻辑分解为一个通用的超类,但是,我想不起来描述性名称的名称。
我之所以尝试使CommandMagager和Command都扩展另一个类的原因是,命令管理器在根级别上的行为类似于命令。命令实际上不包含任何处理命令的逻辑,它们只是提供一种注册和检索具有特定名称的命令的方法。
是否有任何常规约定可以帮助我找到名称,或者这是解决问题的错误方法?
最佳答案
是的,对此有一些规则,没有一成不变的做法,只是一种经验和模仿使它们成为公认的最佳实践。
总览
明确责任。
使用骆驼套。
命名对象,而不是类。
使用名词。
避免使用Info
,Processor
或Manager
之类的词。
如果有对象,请使用单数形式。
对实用程序类使用复数形式。
在Abstract
前面加上抽象基类。
在Impl
后缀隐藏的实现类。
不要在interface
名称前加上I
前缀。
正确使用设计模式名称。
前缀名称及其专业名称。
正确使用数据结构名称
细节
明确责任
重要的是,名称应能很好地反映出责任。名称应传达其意图。
名称对象,而不是类
使用单个对象时看起来不错的名称。命名对象,而不是类。
使用骆驼盒
UseCamelCaseForNamesOfTypesInJava。
使用名词
为对象使用名词。如果对象表示动作,则将动词转换为名词。如果对象表示属性,则将形容词变成名词。例如,如果动作是compile()
,则如果它是主动动作,则使用Compiler
;如果它是被动技能,则使用Compilable
。如果该动作是run()
,则是Runner
,如果它是主动动作,则使用Runnable
,如果它是被动技能。
避免使用Info
,Processor
或Manager
之类的词
在大多数情况下,它们只是“我不知道该怎么称呼”(Robert C. Martin)的同义词。这本身就是“我不知道这件事在做什么”或“这件事在做一件以上的事情”的症状。这就是为什么当我们看到这样的名字时,我们经常正确地感到有重构的渴望。
如果有对象,请使用单数形式
类名通常是单数,特别是如果您可以获得单个类的多个对象。我们喜欢为此类对象的集合的变量名称保留复数形式。
好的例子
JButton button;
List<JButton> buttons;
不好的例子
Properties
是不好的类名,因为尽管有对象,但它是复数。我们喜欢称List<JButton>
jButtons
。那么,您如何称呼List<Properties>
-propertiess
? propertieses
? propertiessies
???对实用程序类使用复数
如果一个类仅包含仅出于为另一种类型提供实用程序方法而存在的静态方法,则该类为实用程序类。
好例子
Collections
,Spilterators
,Arrays
,Executors
,FileSystems
,Files
,Paths
。用
Abstract
前缀抽象基类接口
Foo
的抽象基础实现通常称为AbstractFoo
。示例:
AbstractAction
,AbstractList
,AbstractMap
,AbstractQueue
等。确保此名称是用户几乎看不到的名称,
AbstractSomething
是实现者/扩展者的好名字,而不是用户的好名字。并且仅在没有更好的名称的情况下选择此名称。后缀带有
Impl
的隐藏实现类提供接口或抽象类
Foo
的默认实现的类有时仅称为FooImpl
。确保用户永远不会看到此名称。永远不能。这仅对实现者有益,没有其他人。诸如
XyzImpl
之类的名称对用户不得可见。并且仅在没有更好的名称的情况下选择此名称。不要在
interface
名称前加上I
OO语言中类型的目的通常是封装和隐藏事物。类型是
class
,interface
,enum
还是@interface
注释都是该类型的详细信息。在两种情况下,您需要了解有关类型的这些详细信息:要扩展类型时以及要创建该类型的对象时。这些用例是类型的用例的少数。通过为接口名称加上I
前缀,可以大声地声明实际上应该隐藏的实现细节,从而违反了该原理。将
I
放在interface
的名称之前就像使用匈牙利表示法。仅当您在必须跟踪类型的这些物理方面的环境中工作时,匈牙利符号才有意义。 (因此,这几天在C语言中甚至都没有必要!)此外,当你不想看起来像个白痴
您决定更改接口中的类,反之亦然,并且不重命名类型,最后得到的接口是不带
I
前缀的类或带I
前缀的类。您决定更改界面中的类,反之亦然,然后重命名该类型,最终会惹恼用户。
Oracle消除了Java未来版本中
class
和interface
之间的差异(不太可能,现在看看接口如何具有静态和默认方法)。您将API移植到另一种无法区分
class
和interface
的语言,现在具有带I
前缀的类或具有不同名称的类。正确使用设计模式名称
如果使用设计模式,则可以使用它的名称(如果合适)。但是,如果您不使用设计模式,请避免使用设计模式的名称。
在使用设计模式时,可以选择使用设计模式名称-如果有助于或通常使用设计模式的名称,请使用它,例如抽象工厂的
Factory
后缀。但是,当您实际上不使用设计模式名称时,几乎必须避免使用它。如果您命名为
Command
但未实现命令模式,可能会造成混淆,如果您命名为Strategy
但未实现策略模式,如果您命名为Factory
但未实现策略模式实施Factory模式。这并不总是令人困惑,可能需要做出一些判断。例如,您可能有一个框架来编写带有接口的命令行程序以及这些命令行程序的抽象基类。尽管实际上这不是Command设计模式,但至少从语言本身的角度来看,您可能还是要称它们为
Command
和AbstractCommand
。使用名称的示例
KeyFactory
工厂设计模式DocumentBuilder
生成器设计模式Action
命令设计模式(又名Action,Transaction)不使用名称的示例
Runnable
,Callable
-命令设计模式,但名称不同,但更为专业。Collections.synchronizedList()
-装饰器的工厂方法前缀名称及其专业化
当我们在继承树中向下移动时,类名通常会增长,方法是在基类的名称前加上有关专业化的信息。
例子
List
:AbstractList
,ArrayList
,AbstractSequentialList
,LinkedList
Set
:AbstractSet
,HashSet
,LinkedHashSet
正确使用数据结构名称
如果实现数据结构,请使用适当的名称。
具有键/值对而不管其如何维护的概念称为字典,因此描述该键/值对的接口应命名为字典。 (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
。
关于java - 收集命令对象的名称,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27580974/