在 DDD 中,来自域 类 的 getter 不应以 "get" 为前缀,为什么?

Should getters from domain classes not be prefixed with "get" in DDD, and why?

DDDSample project, now hosted in a Github repository,似乎是一个关于如何设计 DDD 项目的参考。

我注意到域 类 中的所有 getter 都没有以 get 为前缀(例如:Cargo#delivery),而它们在 类 之外的域包(例如:HandlingEventRegistrationAttempt#getTrackingId)。

理查德·C·马丁 (Richard C. Martin) 在他的《整洁代码》(Clean Code) 一书中说:

Accessors, mutators, and predicates should be named for their value and prefixed with get, set, and is according to the javabean standard.

那么,在这种情况下我们应该避免听从他的建议吗?如果是这样,为什么它比一致性更重要?

不幸的是,计算机科学中最难的事情,命名事物,也是最重要的事情。 reader/client 您的代码应该仅通过查看其签名就可以理解该方法的作用。如果他也需要阅读该方法的主体以了解它的作用,那么您就失败了。

因此,如果不知何故,根据某些团队规则或其他原因,您可以理解某个特定方法是 getter 而无需使用 "get" 前缀,那么请不要使用它,否则使用它是因为我们,其他人,希望在 getter.

前面看到 "get"

P.S。这与 DDD 正交。

Why getters from domain classes should not be prefixed with “get” in DDD?

最容易开始的地方是mutators;请注意 Clean Code

中的前一句话

Mutators should have verbs or verb phrase names like postPayment, deletePage, or save.

这个想法与领域模型不应该贫血,领域语言应该无处不在的原则是一致的:我们应该在我们的领域专家在解释业务时使用的代码。

这就是为什么您不会经常看到 set 的原因,除非该动词恰好在您的领域中具有重要意义。

访问器和谓词都是查询的例子。正如 Bertrand Meyer 所理解的那样,查询在不修改实例的情况下提供有关实例的信息,并且它们满足 统一访问原则

from the outside, whether a query is an attribute (field in each object) or a function (algorithm) should not make any difference. For example a_vehicle.speed could be an attribute, accessed from the object's representation; or it could be computed by a function that divides distance by time. The notation is the same in both cases, so that it's easy to change representation without affecting the rest of the software.

那么,这些应该如何命名呢?

Vaughn Vernon,在 Implementing Domain-Driven Design 中写道

The method names of Side-Effect-Free Functions are important. Although these methods all return Values (because they are CQS query methods) they purposely avoid the use of the get-prefix JavaBean naming convention. This simple but effective approach to object design keeps the Value Object faithful to the Ubiquitous Language. The use of getValuePercentage() is a technical computer statement, but valuePercentage() is a fluent human-readable language expression.

Steven Lowe 写道

Developers tend to think and talk in development terms, which naturally results in inadvertent models of how instead of what and why. This is common, and it's a tar pit, because developers tend to follow established patterns. What's more, once the true purpose of the code is obscured, it's unlikely that anyone will unearth it.

我会这样表达这个想法:领域专家应该能够阅读领域模型中的代码,并评估其正确性。这意味着领域代码不应嵌入与基础设施相关的工件。

罗伯特·马丁对这个想法的拼写?

Reader's shouldn't have to mentally translate your names into other names they know.

(Martin 后来断言术语应该取自解决方案领域,前提是大多数读者将是程序员,而不是领域专家。DDD 的反驳论点是程序员应该获得领域专业知识作为他们为企业建模。)

这是一道纯粹而简单的面向对象题。方法必须从接收消息的对象的角度命名,而不是从发送消息的对象的角度命名。 "get" 前缀适合第二种情况。

浏览了repo,我不确定它是否可以称为参考。此外,您应该将 DDD 示例项目视为灵感,而不是要复制的模型。

getter/setters 的命名方式是一个不重要的技术细节您在查看时应该尝试效仿的最后一件事在 DDD 示例代码中。它与DDD无关。至于命名,请使用您自己的 OO 风格(或任何范例)只要名称反映您所在域的通用语言

对我来说,这是那些想在无用的谈话中浪费时间的人关心的事情。

  • 使用 get 前缀可以理解领域概念吗?
  • 你需要前缀吗?

如果你想用 hibernate 做一个领域模型,你必须做 setXXXgetXXX 方法,因为它使用 JavaBean 标准。

这里的要点是 setXXX() 如果暴露可能会很危险,因为你可以跳过你应该在 doTheDomainAction() 方法中实现的一致性控制,所以如果你需要它们可以放他们因为 private 是一个更安全的选择(或者 protected 如果 private 不合适)。

关于 getXXX 方法,我认为如果它们只是用于读取不可变值,那么拥有它们是没有问题的,您唯一需要关心的是它们明确了领域概念,谁会使用它们不能对它们是什么有误解。