我正在开发一个命令处理程序,其中每个命令都可以无限期地拥有子命令。所有命令都由一个" CommandManager"在根级别进行管理。获取用户输入解析选项然后找到正确的命令并将输入传递给它。由于CommandManager和Command都有类似的获取和存储指定命令的方式,并且由于两个类都非常杂乱,我想将找到并存储命令的逻辑分解为一个共同的超类,但是,我可以'想一个描述性名称来称呼它。
我试图让CommandMagager和Command都扩展另一个类的原因是命令管理器就像根级别的命令一样。命令实际上并不包含任何处理命令的逻辑,它们只提供了一种注册和检索具有特定名称的命令的方法。
是否有任何一般惯例可以帮助我找到名称,或者这是错误的方式来查看问题?
答案 0 :(得分:5)
是的,有一些关于这一点的规则,没有一成不变的,只是通过经验和模仿成为公认的最佳实践的实践。
Info
,Processor
或Manager
等字词。Abstract
前缀抽象基类。Impl
隐藏实现类。interface
名称加上I
。重要的是,这个名字很好地反映了责任。名称应传达其意图。
使用在使用单个对象时看起来很好的名称。命名对象,而不是类。
UseCamelCaseForNamesOfTypesInJava。
使用名词作为对象。如果对象表示动作,则将动词转换为名词。如果对象表示属性,则将形容词转换为名词。例如,如果操作为compile()
,则使用Compiler
(如果它是主动操作),或Compilable
(如果它是被动功能)。如果操作为run()
,请使用Runner
(如果是有效操作),Runnable
(如果是被动操作)。
Info
,Processor
或Manager
在大多数情况下,他们只是&#34的同义词;我不知道该怎么称呼这个" (罗伯特C.马丁)。这本身就是一个症状,我不知道这件事在做什么"或者"这件事做的不止一件事"。这就是为什么当我们看到这样的名字时,我们经常理所当然地感受到重构的冲动。
类名通常是单数,特别是如果你可以获得单个类的多个对象。我们希望为这些对象的集合的变量名保留复数。
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
s的名称前加上interface
就像使用匈牙利符号一样。匈牙利符号只有在您需要跟踪类型的这些物理方面的环境中工作时才有意义。 (就此而言,这些日子里在C中甚至没有必要!)
此外,你不想在
时看起来像个白痴I
- 前缀的接口或一个带有I
- 前缀的类。class
和interface
之间的差异(不是那么不可能,现在看看接口如何使用静态和默认方法)。class
和interface
,现在具有I
前缀的类或具有不同名称的类。如果使用设计模式,如果合适,可以使用其名称。但是如果你不使用设计模式,请避免使用设计模式的名称。
在使用设计模式时使用设计模式名称是可选的 - 如果使用设计模式的名称有助于或者通常的做法,请使用它,例如Factory
- 后缀用于抽象工厂。
但是,当您实际不使用设计模式名称时,几乎必须避免使用它。如果您为Command
命名,但它没有实现命令模式,如果您为Strategy
命名,但它没有实现策略模式,如果您为Factory
命名,但它没有实现工厂模式。
它并不总是令人困惑,可能需要一些判断。例如,您可能有一个框架,用于编写带有接口的命令行程序和用于这些命令行程序的抽象基类。您可能希望将它们称为Command
和AbstractCommand
,尽管事实上这不是命令设计模式,至少不是从语言本身的角度来看。
KeyFactory
工厂设计模式DocumentBuilder
Builder 设计模式Action
命令设计模式(又名操作,交易)Runnable
,Callable
- 命令设计模式,但不同的,更专业的名称。Collections.synchronizedList()
- 装饰工具的工厂方法 通过在基类的名称前加上有关特化的信息,在继承树中向前推进,类名称的增长是很常见的。
List
:AbstractList
,ArrayList
,AbstractSequentialList
,LinkedList
Set
:AbstractSet
,HashSet
,LinkedHashSet
如果您实施数据结构,请使用适当的名称。
具有键/值对而不管它们如何维护的概念称为字典,因此描述该键的接口应命名为 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
。
答案 1 :(得分:1)
从您描述模型的方式来看,您看起来正在处理非常接近合成模式的事物(CM是根命令,而C代表单独的命令。) 如果是这种情况,那么您要查找的名称是:
Command
CompositeCommand
SimpleCommand
换句话说,您所谓的CommandManager
将扮演CompositeCommand
的角色,您当前的Command
班级将是SimpleCommand
,最后, (抽象)你正在寻找的超级课程{I} Command
在我提出的术语中。 root用户和任何其他嵌套命令都是CompositeCommand
的实例。当然,如果root有一些特殊的行为,你也可以将其建模为:
Command
CompositeCommand
RootCommand
SimpleCommand
这样,RootCommand
代替你的CommandManager
,它本身是复合的,任何其他带子命令的命令都是CompositeCommand
类,而&#34;叶&#34;将是SimpleCommand
课程。
我知道,有些人不喜欢带有子类的具体类。如果是这种情况,你应该这样做:
Command
CompositeCommand
Subcommand
RootCommand
SimpleCommand
现在Command
和CompositeCommand
是抽象的,所有三个具体类都是子类免费的。
您可能仍在想我为什么要使用这么多名字,而不是CommandManager
。这是因为,在我的观点中,没有命令 manager 这样的东西。
最后,您可能需要另一个对象(来自不同的层次结构),比如CommandParser
,它将以更抽象的方式提供解析服务。 Command
层次结构将使用解析器的服务并将语义添加到否则抽象令牌。这种分离很可能会为Command
代码带来更多简单性。同时,它会将命令语言的语法与内部表示分离,这会为您的设计增加更多的灵活性,因为您可以提供两种不同的语法,而无需修改Command
层次结构。