命名类 - 如何避免将所有内容称为“Manager”?

发布于 2024-08-14 03:44:15 字数 2562 浏览 3 评论 0原文

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

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

那么您能说出这些 UserManagerCompanyManagerAddressManager 的作用吗?不,因为管理器是一个非常通用的术语,适用于您可以对域对象执行的任何操作。

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

或者,UserManager 的工作可能是检查每个 User 对象的数据并以加密方式对数据进行签名。然后我们就有了一个UserRecordsClerk

现在这个想法一直困扰着我,我尝试着应用它。但发现这个简单的想法却异常困难。

我可以描述这些类的作用,并且(只要我不陷入快速而肮脏的编码)我编写的类恰好做一件事。我错过了从描述到名称的一种名称目录,一种将概念映射到名称的词汇表。

最终,我希望在我的脑海中有一个类似模式目录的东西(通常设计模式可以轻松提供对象名称,例如工厂

  • 工厂 - 创建其他对象(取自设计模式的命名)
  • Shepherd - 牧羊人处理对象的生命周期、它们的创建和关闭
  • 同步器 - 在两个或多个对象(或对象层次结构)之间复制数据
  • 保姆 - 帮助对象在创建后达到“可用”状态 - 例如通过连接到其他对象< /p>

  • 等等

那么,你如何处理这个问题呢?您是否有固定的词汇,您是否会临时发明新名称,或者您是否认为命名不那么重要或错误的事物?

PS:我也对讨论该问题的文章和博客的链接感兴趣。首先,这是让我思考这个问题的原始文章: 命名 Java 类没有“经理”


更新:答案摘要

这是我同时从这个问题中学到的一些内容。

  • 尽量不要创建新的隐喻(保姆)
  • 看看其他框架做了什么

有关此主题的更多文章/书籍:

以及我从答案中(主观地!)收集的当前名称前缀/后缀列表:

  • Coordinator
  • Builder
  • Writer
  • Reader
  • Handler
  • Container
  • Protocol
  • Target
  • Converter
  • Controller
  • View
  • Factory
  • Entity
  • Bucket

以及一个很好的提示:

不要陷入命名瘫痪。是的,名字非常重要,但还没有重要到需要浪费大量时间的程度。如果您无法在 10 分钟内想出一个好名字,请继续。

A long time ago I have read an article (I believe a blog entry) which put me on the "right" track on naming objects: Be very very scrupulous about naming things in your program.

For example if my application was (as a typical business app) handling users, companies and addresses I'd have a User, a Company and an Address domain class - and probably somewhere a UserManager, a CompanyManager and an AddressManager would pop up that handles those things.

So can you tell what those UserManager, CompanyManager and AddressManager do? No, because Manager is a very very generic term that fits to anything you can do with your domain objects.

The article I read recommended using very specific names. If it was a C++ application and the UserManager's job was allocating and freeing users from the heap it would not manage the users but guard their birth and death. Hmm, maybe we could call this a UserShepherd.

Or maybe the UserManager's job is to examine each User object's data and sign the data cryptographically. Then we'd have a UserRecordsClerk.

Now that this idea stuck with me I try to apply it. And find this simple idea amazingly hard.

I can describe what the classes do and (as long as I don't slip into quick & dirty coding) the classes I write do exactly one thing. What I miss to go from that description to the names is a kind of catalogue of names, a vocabulary that maps the concepts to names.

Ultimately I'd like to have something like a pattern catalogue in my mind (frequently design patterns easily provide the object names, e.g. a factory)

  • Factory - Creates other objects (naming taken from the design pattern)
  • Shepherd - A shepherd handles the lifetime of objects, their creation and shutdown
  • Synchronizer - Copies data between two or more objects (or object hierarchies)
  • Nanny - Helps objects reach "usable" state after creation - for example by wiring to other objects

  • etc etc.

So, how do you handle that issue? Do you have a fixed vocabulary, do you invent new names on the fly or do you consider naming things not-so-important or wrong?

P.S.: I'm also interested in links to articles and blogs discussing the issue. As a start, here is the original article that got me thinking about it: Naming Java Classes without a 'Manager'


Update: Summary of answers

Here's a little summary of what I learned from this question in the meantime.

  • Try not to create new metaphors (Nanny)
  • Have a look at what other frameworks do

Further articles/books on this topic:

And a current list of name prefixes/suffixes I collected (subjectively!) from the answers:

  • Coordinator
  • Builder
  • Writer
  • Reader
  • Handler
  • Container
  • Protocol
  • Target
  • Converter
  • Controller
  • View
  • Factory
  • Entity
  • Bucket

And a good tip for the road:

Don't get naming paralysis. Yes, names are very important but they're not important enough to waste huge amounts of time on. If you can't think up a good name in 10 minutes, move on.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(12

陪你到最终 2024-08-21 03:44:15

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

看起来 HelperManagerUtil 是您为协调不包含状态且通常是过程性和静态的类而附加的不可避免的名词。另一种选择是协调员。

你可以得到带有名字的特别紫色的散文,比如MinderOverseerSupervisorAdministrator,和 Master,但正如我所说,我更喜欢将其保留为您习惯的框架名称。


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

  • Builder
    使用一些参数来构造特殊类型实例的类型。 Builder 通常是一次性的。它甚至可能不需要分配变量。
    如果类型需要重复创建对象,请使用Factory
    如果类型负责创建多个不同类型的对象,请使用Factories
  • 作家
    将一些变量写入某物中。
  • 阅读器
    将某些内容读取为变量。
  • 处理程序
    旨在处理某种情况或某事。
  • 容器
    可以往里面放东西。

I asked a similar question, but where possible I try to copy the names already in the .NET framework, and I look for ideas in the Java and Android frameworks.

It seems Helper, Manager, and Util are the unavoidable nouns you attach for coordinating classes that contain no state and are generally procedural and static. An alternative is Coordinator.

You could get particularly purple prosey with the names and go for things like Minder, Overseer, Supervisor, Administrator, and Master, but as I said I prefer keeping it like the framework names you're used to.


Some other common suffixes (if that is the correct term) you also find in the .NET framework are:

  • Builder
    A type that use some parameters to construct an instance of a special type. Builder is usually a throwaway. It may not even need to allocate a variable.
    If the type needs to repeatedly create objects, please use Factory.
    if the type responsible for create multiple different type objects, please use Factories.
  • Writer
    Write some variable into something.
  • Reader
    Read something as variable.
  • Handler
    Designed to deal with a situation or something.
  • Container
    Can put something into it.
兰花执着 2024-08-21 03:44:15

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

前 20 名是:

  • 属性
  • 类型
  • 帮助器
  • 集合
  • 转换器
  • 处理程序
  • 信息
  • 提供者
  • 异常
  • 服务
  • 元素
  • 管理
  • 器节点
  • 选项
  • 工厂
  • 上下文
  • 项目
  • 设计
  • 器基本
  • 编辑器

You can take a look at source-code-wordle.de, I have analyzed there the most frequently used suffixes of class names of the .NET framework and some other libraries.

The top 20 are:

  • attribute
  • type
  • helper
  • collection
  • converter
  • handler
  • info
  • provider
  • exception
  • service
  • element
  • manager
  • node
  • option
  • factory
  • context
  • item
  • designer
  • base
  • editor
尸血腥色 2024-08-21 03:44:15

我完全赞成好名字,而且我经常写到在为事物选择名称时要格外小心的重要性。出于同样的原因,我在命名事物时对隐喻持谨慎态度。在最初的问题中,“工厂”和“同步器”看起来像是它们的含义的好名字。然而,“牧羊人”和“保姆”则不然,因为它们是基于隐喻的。代码中的类不能是字面上的保姆;你称它为保姆,因为它照顾其他一些事情,就像现实生活中的保姆照顾婴儿或孩子一样。这在非正式演讲中是可以的,但(在我看来)对于在代码中命名类来说是不行的,因为代码必须由谁知道谁知道何时维护。

为什么?因为隐喻依赖于文化,而且通常也依赖于个人。对你来说,将一个类命名为“nanny”可能非常清楚,但对其他人来说可能不太清楚。我们不应该依赖它,除非您编写的代码仅供个人使用。

无论如何,惯例可以成就一个隐喻,也可以毁掉一个隐喻。 “工厂”本身的使用是基于一个隐喻,但这个隐喻已经存在相当长一段时间了,并且目前在编程世界中相当知名,所以我想说它可以安全使用。但“保姆”和“牧羊人”是不能接受的。

I'm all for good names, and I often write about the importance of taking great care when choosing names for things. For this very same reason, I am wary of metaphors when naming things. In the original question, "factory" and "synchronizer" look like good names for what they seem to mean. However, "shepherd" and "nanny" are not, because they are based on metaphors. A class in your code can't be literally a nanny; you call it a nanny because it looks after some other things very much like a real-life nanny looks after babies or kids. That's OK in informal speech, but not OK (in my opinion) for naming classes in code that will have to be maintained by who knows whom who knows when.

Why? Because metaphors are culture dependent and often individual dependent as well. To you, naming a class "nanny" can be very clear, but maybe it's not that clear to somebody else. We shouldn't rely on that, unless you're writing code that is only for personal use.

In any case, convention can make or break a metaphor. The use of "factory" itself is based on a metaphor, but one that has been around for quite a while and is currently fairly well known in the programming world, so I would say it's safe to use. However, "nanny" and "shepherd" are unacceptable.

玩物 2024-08-21 03:44:15

如果我们正确地对现实世界进行建模,我们可以不需要任何 xxxFactory 、 xxxManager 或 xxxRepository 类:

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

;-)

We could do without any xxxFactory, xxxManager or xxxRepository classes if we modeled the real world correctly:

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

;-)

怀中猫帐中妖 2024-08-21 03:44:15

这听起来像是在 thedailywtf.com 上发布的“ManagerOfPeopleWhoHaveMortgages”等内容的滑坡。

我认为单一的 Manager 类并不是一个好的设计,但使用“Manager”也不错。我们可以将其分解为 UserAccountManager、UserProfileManager、UserSecurityManager 等,而不是 UserManager。

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

It sounds like a slippery slope to something that'd be posted on thedailywtf.com, "ManagerOfPeopleWhoHaveMortgages", etc.

I suppose it's right that one monolithic Manager class is not good design, but using 'Manager' is not bad. Instead of UserManager we might break it down to UserAccountManager, UserProfileManager, UserSecurityManager, etc.

'Manager' is a good word because it clearly shows a class is not representing a real-world 'thing'. 'AccountsClerk' - how am I supposed to tell if that's a class which manages user data, or represents someone who is an Accounts Clerk for their job?

世态炎凉 2024-08-21 03:44:15

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

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

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

技术基础设施类要容易一些,因为它们描述了我们非常熟悉的领域。我更喜欢将设计模式名称合并到类名称中,例如 InsertUserCommand、 CustomerRepositorySapAdapter。 我理解对通信实现的关注,而不是意图,但设计模式将类设计的这两个方面结合在一起 - 至少在处理基础设施时,您希望实现设计是透明的,即使您隐藏了细节。

When I find myself thinking about using Manager or Helper in a class name, I consider it a code smell that means I haven't found the right abstraction yet and/or I'm violating the single responsibility principle, so refactoring and putting more effort into design often makes naming much easier.

But even well-designed classes don't (always) name themselves, and your choices partly depend on whether you're creating business model classes or technical infrastructure classes.

Business model classes can be hard, because they're different for every domain. There are some terms I use a lot, like Policy for strategy classes within a domain (e.g., LateRentalPolicy), but these usually flow from trying to create a "ubiquitous language" that you can share with business users, designing and naming classes so they model real-world ideas, objects, actions, and events.

Technical infrastructure classes are a bit easier, because they describe domains we know really well. I prefer to incorporate design pattern names into the class names, like InsertUserCommand, CustomerRepository, or SapAdapter. I understand the concern about communicating implementation instead of intent, but design patterns marry these two aspects of class design - at least when you're dealing with infrastructure, where you want the implementation design to be transparent even while you're hiding the details.

笑看君怀她人 2024-08-21 03:44:15

熟悉GOF 书定义的模式,并命名这些之后的对象让我在命名类、组织它们和传达意图方面取得了长足的进步。大多数人都会理解这个术语(或至少它的主要部分)。

Being au fait with patterns as defined by (say) the GOF book, and naming objects after these gets me a long way in naming classes, organising them and communicating intent. Most people will understand this nomenclature (or at least a major part of it).

晨与橙与城 2024-08-21 03:44:15

如果我无法为我的类提供比 XyzManager 更具体的名称,那么我需要重新考虑这是否真的是属于一个类的功能,即架构“代码味道”。

If I cannot come up with a more concrete name for my class than XyzManager this would be a point for me to reconsider whether this is really functionality that belongs together in a class, i.e. an architectural 'code smell'.

写给空气的情书 2024-08-21 03:44:15

我认为最重要的是要记住:名称是否足够具有描述性?你能通过看名字就知道这个类应该做什么吗?在类名中使用“Manager”、“Service”或“Handler”等词可能会被认为过于通用,但由于很多程序员都使用它们,因此它也有助于理解类的用途。

我自己也经常使用门面模式(至少,我认为它是这么叫的)。我可以有一个仅描述一个用户的 User 类,以及一个跟踪我的“用户集合”的 Users 类。我不将该类称为 UserManager 因为我不喜欢现实生活中的管理者,并且我不想被提醒他们:) 简单地使用复数形式可以帮助我理解类确实如此。

I think the most important thing to keep in mind is: is the name descriptive enough? Can you tell by looking at the name what the Class is supposed to do? Using words like "Manager", "Service" or "Handler" in your class names can be considered too generic, but since a lot of programmers use them it also helps understanding what the class is for.

I myself have been using the facade-pattern a lot (at least, I think that's what it is called). I could have a User class that describes just one user, and a Users class that keeps track of my "collection of users". I don't call the class a UserManager because I don't like managers in real-life and I don't want to be reminded of them :) Simply using the plural form helps me understand what the class does.

洒一地阳光 2024-08-21 03:44:15

具体到 C#,我找到了 “框架设计指南:可重用 .NET 的约定、习惯用法和模式”库” 拥有大量有关命名逻辑的有用信息。

不过,就找到那些更具体的单词而言,我经常使用同义词库并跳过相关单词来尝试找到一个好的单词。不过,我尽量不要花太多时间在它上面,随着我在开发过程中的进展,我会想出更好的名称,或者有时意识到 SuchAndSuchManager 确实应该分解为多个类,然后使用那个已弃用的类不再是问题。

Specific to C#, I found "Framework Design Guidelines: Conventions, Idioms, and Patterns for Reusable .NET Libraries" to have lots of good information on the logic of naming.

As far as finding those more specific words though, I often use a thesaurus and jump through related words to try and find a good one. I try not to spend to much time with it though, as I progress through development I come up with better names, or sometimes realize that SuchAndSuchManager should really be broken up into multiple classes, and then the name of that deprecated class becomes a non-issue.

阪姬 2024-08-21 03:44:15

我认为这里的关键是在代码可见性范围内保持一致,即只要需要查看/处理代码的每个人都理解您的命名约定,那么就应该没问题,即使您决定调用它们“CompanyThingamabob”和“UserDoohickey”。如果您在公司工作,第一站是查看公司是否有命名惯例。如果没有或者您不在公司工作,那么创建您自己的对您有意义的使用术语,将其传递给一些至少会随意编码的值得信赖的同事/朋友,并纳入任何有意义的反馈。

在我的书中,应用别人的惯例,即使它被广泛接受,如果它没有跳出页面,那就是一个错误。首先也是最重要的,我需要在不参考其他文档的情况下理解我的代码,但同时它需要足够通用,以便对于同一行业同一领域的其他人来说并不是难以理解的。

I believe the critical thing here is to be consistent within the sphere of your code's visibility, i.e. as long as everyone who needs to look at/work on your code understands your naming convention then that should be fine, even if you decide to call them 'CompanyThingamabob' and 'UserDoohickey'. The first stop, if you work for a company, is to see if there is a company convention for naming. If there isn't or you don't work for a company then create your own using terms that make sense to you, pass it around a few trusted colleagues/friends who at least code casually, and incorporate any feedback that makes sense.

Applying someone else's convention, even when it's widely accepted, if it doesn't leap off the page at you is a bit of a mistake in my book. First and foremost I need to understand my code without reference to other documentation but at the same time it needs to be generic enough that it's no incomprehensible to someone else in the same field in the same industry.

断肠人 2024-08-21 03:44:15

我会考虑您在系统中使用的模式,类的命名约定/编目/分组往往是由所使用的模式定义的。就我个人而言,我坚持这些命名约定,因为它们是其他人能够获取我的代码并运行它的最有可能的方式。

例如,UserRecordsClerk 可能更好地解释为扩展通用 RecordsClerk 接口,UserRecordsClerk 和 CompanyRecordsClerk 都实现该接口,然后专门化,这意味着人们可以查看接口中的方法以了解其子类的用途/一般用途。

请参阅设计模式之类的书籍信息,这是一本很棒的书,可能会帮助您明确代码的目标 - 如果您还没有使用它! ;o)

我认为只要你的模式选择得当并且使用得当,那么相当简单的简单类名就足够了!

I'd consider the patterns you are using for your system, the naming conventions / cataloguing / grouping of classes of tends to be defined by the pattern used. Personally, I stick to these naming conventions as they are the most likely way for another person to be able to pick up my code and run with it.

For example UserRecordsClerk might be better explained as extending a generic RecordsClerk interface that both UserRecordsClerk and CompanyRecordsClerk implement and then specialise on, meaning one can look at the methods in the interface to see what the its subclasses do / are generally for.

See a book such as Design Patterns for info, it's an excellent book and might help you clear up where you're aiming to be with your code - if you aren't already using it! ;o)

I reckon so long as your pattern is well chosen and used as far as is appropriate, then pretty uninventive straightforward class names should suffice!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文