题 命名类 - 如何避免将所有内容称为“ Manager”? [关闭]


很久以前我读过一篇文章(我相信一篇博客文章),它让我在命名对象的“正确”轨道上:非常非常谨慎地命名程序中的东西。

例如,如果我的应用程序(作为一个典型的商业应用程序)处理用户,公司和地址,我有一个 User, 一个 Company 和 Address 域类 - 可能在某个地方 UserManager, 一个 CompanyManager 和 AddressManager 会弹出来处理这些事情。

所以你能说出那些 UserManagerCompanyManager 和 AddressManager 做?不,因为Manager是一个非常通用的术语,适用于您可以对域对象执行的任何操作。

我读过的文章建议使用非常具体的名称。如果它是一个C ++应用程序和 UserManager的工作是分配和释放用户从堆中,它不会管理用户,但保护他们的出生和死亡。嗯,也许我们可以称之为 UserShepherd

或者也许是 UserManager的工作是检查每个用户对象的数据并以加密方式签署数据。然后我们有一个 UserRecordsClerk

现在这个想法一直困扰着我,我尝试应用它。并且非常难以找到这个简单的想法。

我可以描述这些类的作用,并且(只要我没有进入快速和脏编码)我写的类完全正确  事情。我想念从名称到名称的是一种名称目录,一种将概念映射到名称的词汇表。

最终,我想在我的脑海里有类似图案目录的东西(通常设计图案很容易提供对象名称,例如

  • Factory - 创建其他对象(从设计模式中命名)
  • 牧羊人 - 牧羊人处理物体的生命,它们的创建和关闭
  • 同步器 - 在两个或多个对象(或对象层次结构)之间复制数据
  • 保姆 - 帮助对象在创建后达到“可用”状态 - 例如通过连接到其他对象

  • 等等

那么,你如何处理这个问题呢?你有一个固定的词汇表,你是否动态发明新的名字,或者你认为命名的东西不是那么重要或错误?

P.S。:我也对链接​​到讨论这个问题的文章和博客感兴趣。首先,这是让我思考它的原始文章: 在没有“经理”的情况下命名Java类


更新:答案摘要

以下是我在此期间从这个问题中学到的内容的一些总结。

  • 尽量不要创造新的比喻(保姆)
  • 看看其他框架的作用

关于这个主题的进一步文章/书籍:

并且我从答案中收集了(主观上!)的当前名称前缀/后缀列表:

  • 协调员
  • 生成器
  • 作家
  • 读者
  • 处理器
  • 容器
  • 协议
  • 目标
  • 变流器
  • 调节器
  • 视图
  • 实体

这条道路的一个好建议:

不要命名瘫痪。是的,名字非常重要,但它们不足以浪费大量时间。如果你不能在10分钟内想出一个好名字,继续前进。


939
2017-12-08 13:26


起源


它属于社区维基,因为没有一个“最佳”答案。这是一个讨论。 - DOK
这是违反直觉的。他们不应该把它称为论坛吗?我认为维基会收集事实,而不是意见。 - AaronLS
感谢您保持更新 - 但是,最后一个提示是可怕的建议!如果你在10分钟内想不出一个好名字,你的班级可能有问题。 (标准警告:1)完美是善的敌人,2)航运是一个特征 - 只要记住你正在承担技术债务。) - Jeff Sternal
如果你在10分钟内想不出一个好名字,那就请你的同事寻求帮助。不要只是放弃。
如果你不能在10分钟内想出一个好名字,试着向你的同事解释一下;他们 威力 想到一个好名字(user338195),但试图解释它可能会帮助你发现它的错误(杰夫)。 - WillC


答案:


我问了一个 类似的问题,但在可能的情况下,我尝试复制已经在.NET框架中的名称,并在Java和Android框架中寻找想法。

它似乎 HelperManager,和 Util 是你附加的不可避免的名词,用于协调不包含状态的类,通常是程序性的和静态的。另一种选择是 Coordinator

你可以用名字获得特别紫色的散文并且去寻找类似的东西 MinderOverseerSupervisorAdministrator,和 Master,但正如我所说,我更喜欢保持它像你习惯的框架名称。

您在.NET框架中找到的一些其他常见后缀(如果这是正确的术语)是:

  • Builder
  • Writer
  • Reader
  • Handler
  • Container

153
2017-12-08 12:59



我非常喜欢这些。它们不会陷入糟糕或未知隐喻的陷阱,因为它们已经被.NET Framework使用。查看其他库(Java)也可能很有趣,以获得更多常用的输入。 - froh42
我想建议 Conductor,就像音乐乐团的指挥。它肯定是一个重要的角色,取决于你需要“进行”的合作的性质(其他对象是非常专业的演员,应该响应集中命令,不要太担心其他所有合作者)。 - heltonbiker


你可以看看 source-code-wordle.de,我已经分析了.NET框架和其他一些库的类名最常用的后缀。

前20名是:

  • 属性
  • 类型
  • 帮手
  • 采集
  • 变流器
  • 处理器
  • 信息
  • 提供商
  • 例外
  • 服务
  • 元件
  • 经理
  • 节点
  • 选项
  • 上下文
  • 项目
  • 设计师
  • 基础
  • 编辑

88
2017-12-08 13:13



很久以前,在一家特定的公司,我认识一位工程师如此厌倦了荒谬和越来越多的后缀规则,这些规则困扰着公司,他顽固地结束了每一堂课。 Thingy。


我只是为了好名字而且我经常写下在选择名字时要特别小心的重要性。出于同样的原因,在命名事物时我对隐喻很谨慎。在最初的问题中,“工厂”和“同步器”看起来就像它们似乎意味着的好名字。然而,“牧羊人”和“保姆”不是,因为它们是基于 隐喻。代码中的类不能 按照字面 一个保姆;你称它为保姆,因为它照顾其他一些东西,非常像现实生活中的保姆照顾婴儿或小孩。这在非正式演讲中是可以的,但不是(在我看来)可以在代码中命名类,这些代码必须由谁知道谁知道何时知道。

为什么?因为隐喻是文化依赖的,并且通常也是个人依赖的。对你来说,命名一个班级“保姆”可以非常清楚,但也许对其他人来说并不是那么清楚。除非您编写的代码仅供个人使用,否则我们不应该依赖它。

在任何情况下,惯例都可以成就或破坏隐喻。 “工厂”本身的使用是基于一个比喻,但它已经存在了很长一段时间,并且目前在编程世界中是众所周知的,所以我认为使用它是安全的。然而,“保姆”和“牧羊人”是不可接受的。


51
2017-12-08 13:18



+1用于避免对其他人来说难以理解的隐喻 - rossoft
这个论点真的打破了,显然工厂本身就是一个比喻。隐喻通常会清除对象可能擅长的内容,而模糊或通用自动确保通过完全阅读它来找出代码所做的唯一方法!最糟糕的情况。 - Kzqai
+1用于避免'可爱'的名字。我认为尽可能直接使用语言是很棒的。 (当然,直接,简洁,精确并不总是那么容易 和 所有在同一时间明确......) - andrewf


我们可以做到没有 xxxFactoryxxxManager 要么 xxxRepository 如果我们正确地模拟现实世界的类:

Universe.Instance.Galaxies["Milky Way"].SolarSystems["Sol"]
        .Planets["Earth"].Inhabitants.OfType<Human>().WorkingFor["Initech, USA"]
        .OfType<User>().CreateNew("John Doe");

;-)


39
2017-12-08 13:02



您将如何获得并行Universe和备用维度? - tster
这很容易:Omniverse.Instance.Dimensions [“我们的”]。宇宙[“我们的”]。星系......好吧我承认这需要重新编译。 ;-) - herzmeister
更新: 这是在.NET 4.0中添加的: Universe.Instance.ToParallel() ;) - Connell
虽然打破了德米特定律! - Jonas G. Drange
那些是对象和成员,而不是类名 - Harry Berry


对于会发布在thedailywtf.com,“ManagerOfPeopleWhoHaveMortgages”等上的东西,这听起来像是一个滑坡。

我认为一个单一的Manager类不是好设计是正确的,但使用'Manager'并不错。我们可能会将其分解为UserAccountManager,UserProfileManager,UserSecurityManager等,而不是UserManager。

“经理”是一个好词,因为它清楚地表明一个班级并不代表现实世界的“事物”。 'AccountsClerk' - 我该如何判断这是一个管理用户数据的类,还是代表某人作为他们工作的会计文员?


31
2017-12-08 13:12



UserAccounter,UserProfiler和UserSecurer怎么样?如果你摆脱了经理,你被迫提出具体的定义,我认为这是一件好事。 - Didier A.
UserAccount,UserProfile,UserSecurity oO怎么样? - clime
我会把它命名为“MortageOwnersManager” - volter9
有时域名具有特定名称。像“MortageHolder”一样可能更好“MortageOwner” - borjab


由于你对这个领域的文章感兴趣,你可能会对Steve Yegge的观点文章“名词王国的执行”感兴趣:

http://steve-yegge.blogspot.com/2006/03/execution-in-kingdom-of-nouns.html


19





当我发现自己在考虑使用时 Manager 要么 Helper 在一个类名中,我认为它是一种代码味道,这意味着我还没有找到正确的抽象和/或我违反了 单一责任原则因此,重构并在设计上投入更多精力通常会使命名变得更加容易。

但即使是精心设计的类也不会(总是)为自己命名,而您的选择部分取决于您是创建业务模型类还是技术基础结构类。

业务模型类可能很难,因为它们对于每个域都是不同的。有一些我经常使用的术语,比如 Policy 对于域内的策略类(例如, LateRentalPolicy),但这些通常来自试图创造“无处不在的语言“您可以与业务用户共享,设计和命名类,以便他们模拟真实世界的想法,对象,操作和事件。

技术基础设施类更容易,因为它们描述了我们非常熟悉的域。我更喜欢将设计模式名称合并到类名中,比如 InsertUserCommand,  CustomerRepository, 要么 SapAdapter. 我理解关于沟通实现而非意图的关注,但设计模式与类设计的这两个方面相结合 - 至少在您处理基础架构时,您希望实现 设计 即使你隐藏细节也要透明。


16



我真的很喜欢使用它的想法 Policy 包含业务逻辑的类的后缀 - jtate


因为(例如)所定义的模式而具有自我效果 GOF书,并在这些命名对象之后让我在命名类,组织它们和传达意图方面有很长的路要走。大多数人会理解这种命名法(或至少是其中的一个主要部分)。


8



福勒对我来说是一个很好的参考,但GOF是一个很好的推荐。 - Lazarus
原谅我的无知。你指的是哪本福勒书? - Brian Agnew
amazon.com/Patterns-Enterprise-Application-Architecture-Martin/... - Jim Ferrans
嗯,有时这很有效(例如像工厂或战略)但在其他时候我觉得这确实传达了实现的方式(我使用了模式!)而不是类的意图和工作。例如,单身人士最重要的是它代表什么 - 而不是单身人士。在使用的模式之后如此严格的命名感觉就像在使用的类型之后严格命名。例如,由Windows系统组错误应用的匈牙利表示法(描述C数据类型而不是“意图类型”) - froh42
对于技术基础结构类,通常需要使实现透明 - 大多数规范设计模式名称都要实现实现和意图。但是,域模型类是另一回事。 - Jeff Sternal