很久以前我读过一篇文章(我相信一篇博客文章),它让我在命名对象的“正确”轨道上:非常非常谨慎地命名程序中的东西。
例如,如果我的应用程序(作为一个典型的商业应用程序)处理用户,公司和地址,我有一个 User
, 一个 Company
和 Address
域类 - 可能在某个地方 UserManager
, 一个 CompanyManager
和 AddressManager
会弹出来处理这些事情。
所以你能说出那些 UserManager
, CompanyManager
和 AddressManager
做?不,因为Manager是一个非常通用的术语,适用于您可以对域对象执行的任何操作。
我读过的文章建议使用非常具体的名称。如果它是一个C ++应用程序和 UserManager
的工作是分配和释放用户从堆中,它不会管理用户,但保护他们的出生和死亡。嗯,也许我们可以称之为 UserShepherd
。
或者也许是 UserManager
的工作是检查每个用户对象的数据并以加密方式签署数据。然后我们有一个 UserRecordsClerk
。
现在这个想法一直困扰着我,我尝试应用它。并且非常难以找到这个简单的想法。
我可以描述这些类的作用,并且(只要我没有进入快速和脏编码)我写的类完全正确 一 事情。我想念从名称到名称的是一种名称目录,一种将概念映射到名称的词汇表。
最终,我想在我的脑海里有类似图案目录的东西(通常设计图案很容易提供对象名称,例如 厂)
那么,你如何处理这个问题呢?你有一个固定的词汇表,你是否动态发明新的名字,或者你认为命名的东西不是那么重要或错误?
P.S。:我也对链接到讨论这个问题的文章和博客感兴趣。首先,这是让我思考它的原始文章: 在没有“经理”的情况下命名Java类
更新:答案摘要
以下是我在此期间从这个问题中学到的内容的一些总结。
关于这个主题的进一步文章/书籍:
并且我从答案中收集了(主观上!)的当前名称前缀/后缀列表:
- 协调员
- 生成器
- 作家
- 读者
- 处理器
- 容器
- 协议
- 目标
- 变流器
- 调节器
- 视图
- 厂
- 实体
- 桶
这条道路的一个好建议:
不要命名瘫痪。是的,名字非常重要,但它们不足以浪费大量时间。如果你不能在10分钟内想出一个好名字,继续前进。
我问了一个 类似的问题,但在可能的情况下,我尝试复制已经在.NET框架中的名称,并在Java和Android框架中寻找想法。
它似乎 Helper
, Manager
,和 Util
是你附加的不可避免的名词,用于协调不包含状态的类,通常是程序性的和静态的。另一种选择是 Coordinator
。
你可以用名字获得特别紫色的散文并且去寻找类似的东西 Minder
, Overseer
, Supervisor
, Administrator
,和 Master
,但正如我所说,我更喜欢保持它像你习惯的框架名称。
您在.NET框架中找到的一些其他常见后缀(如果这是正确的术语)是:
Builder
Writer
Reader
Handler
Container
你可以看看 source-code-wordle.de,我已经分析了.NET框架和其他一些库的类名最常用的后缀。
前20名是:
- 属性
- 类型
- 帮手
- 采集
- 变流器
- 处理器
- 信息
- 提供商
- 例外
- 服务
- 元件
- 经理
- 节点
- 选项
- 厂
- 上下文
- 项目
- 设计师
- 基础
- 编辑
我只是为了好名字而且我经常写下在选择名字时要特别小心的重要性。出于同样的原因,在命名事物时我对隐喻很谨慎。在最初的问题中,“工厂”和“同步器”看起来就像它们似乎意味着的好名字。然而,“牧羊人”和“保姆”不是,因为它们是基于 隐喻。代码中的类不能 按照字面 一个保姆;你称它为保姆,因为它照顾其他一些东西,非常像现实生活中的保姆照顾婴儿或小孩。这在非正式演讲中是可以的,但不是(在我看来)可以在代码中命名类,这些代码必须由谁知道谁知道何时知道。
为什么?因为隐喻是文化依赖的,并且通常也是个人依赖的。对你来说,命名一个班级“保姆”可以非常清楚,但也许对其他人来说并不是那么清楚。除非您编写的代码仅供个人使用,否则我们不应该依赖它。
在任何情况下,惯例都可以成就或破坏隐喻。 “工厂”本身的使用是基于一个比喻,但它已经存在了很长一段时间,并且目前在编程世界中是众所周知的,所以我认为使用它是安全的。然而,“保姆”和“牧羊人”是不可接受的。
我们可以做到没有 xxxFactory
, xxxManager
要么 xxxRepository
如果我们正确地模拟现实世界的类:
Universe.Instance.Galaxies["Milky Way"].SolarSystems["Sol"]
.Planets["Earth"].Inhabitants.OfType<Human>().WorkingFor["Initech, USA"]
.OfType<User>().CreateNew("John Doe");
;-)
对于会发布在thedailywtf.com,“ManagerOfPeopleWhoHaveMortgages”等上的东西,这听起来像是一个滑坡。
我认为一个单一的Manager类不是好设计是正确的,但使用'Manager'并不错。我们可能会将其分解为UserAccountManager,UserProfileManager,UserSecurityManager等,而不是UserManager。
“经理”是一个好词,因为它清楚地表明一个班级并不代表现实世界的“事物”。 'AccountsClerk' - 我该如何判断这是一个管理用户数据的类,还是代表某人作为他们工作的会计文员?
当我发现自己在考虑使用时 Manager
要么 Helper
在一个类名中,我认为它是一种代码味道,这意味着我还没有找到正确的抽象和/或我违反了 单一责任原则因此,重构并在设计上投入更多精力通常会使命名变得更加容易。
但即使是精心设计的类也不会(总是)为自己命名,而您的选择部分取决于您是创建业务模型类还是技术基础结构类。
业务模型类可能很难,因为它们对于每个域都是不同的。有一些我经常使用的术语,比如 Policy
对于域内的策略类(例如, LateRentalPolicy
),但这些通常来自试图创造“无处不在的语言“您可以与业务用户共享,设计和命名类,以便他们模拟真实世界的想法,对象,操作和事件。
技术基础设施类更容易,因为它们描述了我们非常熟悉的域。我更喜欢将设计模式名称合并到类名中,比如 InsertUserCommand,
CustomerRepository,
要么 SapAdapter.
我理解关于沟通实现而非意图的关注,但设计模式与类设计的这两个方面相结合 - 至少在您处理基础架构时,您希望实现 设计 即使你隐藏细节也要透明。
因为(例如)所定义的模式而具有自我效果 GOF书,并在这些命名对象之后让我在命名类,组织它们和传达意图方面有很长的路要走。大多数人会理解这种命名法(或至少是其中的一个主要部分)。