烂翻译系列之学习领域驱动设计——第三章:管理领域复杂性

As you saw in the previous chapter, to ensure a project’s success it’s crucial that you develop a ubiquitous language that can be used for communication by all stakeholders, from software engineers to domain experts. The language should reflect the domain experts’ mental models of the business domain’s inner workings and underlying principles.

正如您在上一章中看到的,为了确保项目的成功,开发通用语言是至关重要的,这种语言可以用于从软件工程师到领域专家的所有利益相关者之间的沟通。这种语言应该反映领域专家对业务领域内部运作和基础原则的心智模型。

Since our goal is to use ubiquitous language to drive software design decisions, the language must be clear and consistent. It should be free of ambiguity, implicit assumptions, and extraneous details. However, on an organizational scale, the domain experts’ mental models can be inconsistent themselves. Different domain experts can use different models of the same business domain. Let’s take a look at an example.

因为我们的目标是使用通用语言来驱动软件设计决策,所以这种语言必须是清晰和一致的。它应该没有歧义、隐含的假设和多余的细节。然而,在组织层面上,领域专家的心理模型本身可能并不一致。不同的领域专家可能会对相同的业务领域使用不同的模型。让我们来看一个例子。

Inconsistent Models

不一致的模型

Let’s go back to the example of a telemarketing company from Chapter 2. The company’s marketing department generates leads through online advertisements. Its sales department is in charge of soliciting prospective customers to buy its products or services, a chain that is shown in Figure 3- 1.

让我们回到第2章中电话营销公司的例子。该公司的市场部门通过在线广告吸引和获取潜在客户。其销售部门负责向潜在客户推销其产品或服务,这一流程如图3-1所示。

 

Figure 3-1. Example business domain: telemarketing company

图3-1.示例业务领域: 电话营销公司

An examination of the domain experts’ language reveals a peculiar observation. The term lead has different meanings in the marketing and sales departments:

对领域专家的语言的研究揭示了一个奇特的现象。“lead”一词在市场营销部门和销售部门有不同的含义:

Marketing department

市场营销部门

For the marketing people, a lead represents a notification that somebody is interested in one of the products. The event of receiving the prospective customer’s contact details is considered a lead.

对于营销人员来说,lead(销售线索)表示有人对某个产品感兴趣的通知。收到潜在客户联系信息的事件被视为销售线索。

Sales department

销售部门

In the context of the sales department, a lead is a much more complex entity. It represents the entire lifecycle of the sales process. It’s not a mere event, but a long-running process.

在销售部门中,lead是一个更加复杂的实体。它代表了销售过程的整个生命周期。它不仅仅是一个事件,而是一个长期运行的过程。

How do we formulate a ubiquitous language in the case of this telemarketing company?

在这种情况下,我们如何为这家电话销售公司制定通用语言?

On the one hand, we know the ubiquitous language has to be consistent— each term should have one meaning. On the other hand, we know the ubiquitous language has to reflect the domain experts’ mental models. In this case, the mental model of the “lead” is inconsistent among the domain experts in the sales and marketing departments.

一方面,我们知道通用语言必须是一致的——每个术语都应该有一个意思。另一方面,我们知道通用语言必须反映领域专家的心理模型。在这种情况下,在销售和营销部门的领域专家中,“lead”的心智模型是不一致的。

This ambiguity doesn’t present that much of a challenge in person-to-person communications. Indeed, communication can be more challenging among people from different departments, but it’s easy enough for humans to infer the exact meaning from the interaction’s context.

在人与人之间的交流中,这种模糊性并不构成太大的挑战。事实上,不同部门的人之间的交流更具挑战性,但是人们很容易从交流的背景中推断出确切的含义。

However, it is more difficult to represent such a divergent model of the business domain in software. Source code doesn’t cope well with ambiguity. If we were to bring the sales department’s complicated model into marketing, it would introduce complexity where it’s not needed— far more detail and behavior than marketing people need for optimizing advertising campaigns. But if we were to try to simplify the sales model according to the marketing world view, it wouldn’t fit the sales subdomain’s needs, because it’s too simplistic for managing and optimizing the sales process. We’d have an overengineered solution in the first case and an under-engineered one in the second.

然而,在软件中表示这样一个业务领域的分歧模型是比较困难的。源代码不能很好地处理模糊性。如果我们将销售部门的复杂模式引入市场营销部门,它会在不需要的地方引入复杂性ーー比市场营销人员优化广告活动所需的细节和行为要复杂得多。但是,如果我们试图根据市场营销的世界观来简化销售模型,它就不能满足销售子域的需要,因为它过于简单,无法管理和优化销售过程。在第一种情况下,我们会得到一个过度设计的解决方案,而在第二种情况下,会得到一个设计不足的解决方案。

How do we solve this catch-22?

我们如何解决这种两难困境?

The traditional solution to this problem is to design a single model that can be used for all kinds of problems. Such models result in enormous entity relationship diagrams (ERDs) spanning whole office walls. Is Figure 3-2 an effective model?

解决这个问题的传统方法是设计一个可以用于各种问题的单一模型。这种模型会产生巨大的实体关系图(ERD),它们覆盖整个办公室的墙壁。图3-2是一个有效的模型吗?

 

Figure 3-2. Enterprise-wide entity relationship diagram

图3-2. 企业级实体关系图

As the saying goes, “jack of all trades, master of none.” Such models are supposed to be suitable for everything but eventually are effective for nothing. No matter what you do, you are always facing complexity: the complexity of filtering out extraneous details, the complexity of finding what you do need, and most importantly, the complexity of keeping the data in a consistent state.

俗话说,“样样通,样样松。” 这种模型应该适用于所有情况,但最终却是无效的。无论你做什么,你总是会面临复杂性:过滤掉多余细节的复杂性,找到你真正需要的复杂性,以及最重要的是,保持数据一致状态的复杂性。

Another solution would be to prefix the problematic term with a definition of the context: “marketing lead” and “sales lead.” That would allow the implementation of the two models in code. However, this approach has two main disadvantages. First, it induces cognitive load. When should each model be used? The closer the implementations of the conflicting models are, the easier it is to make a mistake. Second, the implementation of the model won’t be aligned with the ubiquitous language. No one would use the prefixes in conversations. People don’t need this extra information; they can rely on the conversation’s context.

另一个解决方案是在有疑问的术语前面加上上下文的定义: “营销lead”和“销售lead”这将允许在代码中实现这两个模型。但是,这种方法有两个主要缺点。首先,它增加了认知负担。每种模型应在何时使用?冲突模型的实现越接近,就越容易出错。其次,模型的实现将与通用语言冲突。没有人会在谈话中使用前缀。人们不需要这些额外的信息; 他们可以依赖于谈话的环境。

Let’s turn to the domain-driven design pattern for tackling such scenarios: the bounded context pattern.

让我们转向处理这类场景的领域驱动设计模式: 有界上下文模式。

What Is a Bounded Context?

有界上下文是什么?

The solution in domain-driven design is trivial: divide the ubiquitous language into multiple smaller languages, then assign each one to the explicit context in which it can be applied: its bounded context.

领域驱动设计的解决方案是很简单的:将通用语言划分为多个较小的语言,然后将每个语言分配给可以应用的明确上下文:其有界上下文。

In the preceding example, we can identify two bounded contexts: marketing and sales. The term lead exists in both bounded contexts, as shown in Figure 3-3. As long as it bears a single meaning in each bounded context, each fine-grained ubiquitous language is consistent and follows the domain experts’ mental models.

在前面的例子中,我们可以确定两个有界上下文: 市场营销和销售。术语“lead”同时存在于两种有界上下文中,如图3-3所示。只要它在每个有界上下文中具有单一的意义,每个细粒度的通用语言就是一致的,并遵循领域专家的心智模型。

 

Figure 3-3. Tackling inconsistencies in the ubiquitous language by splitting it into bounded contexts

图3-3.  通过将通用语言拆分为有界上下文来解决其中的冲突

In a sense, terminology conflicts and implicit contexts are an inherent part of any decent-sized business. With the bounded context pattern, the contexts are modeled as an explicit and integral part of the business domain.

从某种意义上说,术语冲突和隐式上下文是任何规模较大的业务的固有组成部分。使用有界上下文模式,上下文被建模为业务领域的一个明确的、不可分割的部分。

Model Boundaries

模型边界

As we discussed in the previous chapter, a model is not a copy of the real world but a construct that helps us make sense of a complex system. The problem it is supposed to solve is an inherent part of a model—its purpose. A model cannot exist without a boundary; it will expand to become a copy of the real world. That makes defining a model’s boundary—its bounded contexts—an intrinsic part of the modeling process.

正如我们在前一章中所讨论的,模型不是现实世界的副本,而是一个有助于我们理解复杂系统的构造。模型所要解决的问题是一个模型固有的一部分——它的目的。模型不能没有边界,那样它会扩展成为现实世界的一个副本。这使得定义模型的边界——它的有界上下文——成为建模过程的固有部分。

Let’s go back to the example of maps as models. We saw that each map has its specific context—aerial, nautical, terrain, subway, and so on. A map is useful and consistent only within the scope of its specific purpose.

让我们回到地图作为模型的例子。我们看到,每张地图都有其特定的上下文——航空图、航海图、地形图、地铁图等等。地图只有在其特定用途的范围内才是有用和一致的。

Just as a subway map is useless for nautical navigation, a ubiquitous language in one bounded context can be completely irrelevant to the scope of another bounded context. Bounded contexts define the applicability of a ubiquitous language and of the model it represents. They allow defining distinct models according to different problem domains. In other words, bounded contexts are the consistency boundaries of ubiquitous languages. A language’s terminology, principles, and business rules are only consistent inside its bounded context.

正如地铁地图对于航海导航毫无用处一样,在一个有界上下文中的通用语言可能与另一个有界上下文的范围完全无关。有界上下文定义了一种通用语言及其所代表的模型的适用性。它们允许根据不同的问题域定义不同的模型。换句话说,有界上下文是通用语言的一致性边界。一种语言的术语、原则和业务规则只有在其有界上下文内部保持一致。

Ubiquitous Language Refined

精炼的通用语言

Bounded contexts allow us to complete the definition of a ubiquitous language. A ubiquitous language is not “ubiquitous” in the sense that it should be used and applied “ubiquitously” throughout the organization. A ubiquitous language is not universal.

有界上下文使我们能够完善通用语言的定义。通用语言并不是指应该在整个组织中“普遍”使用和应用的意思。通用语言不是通用的,它是特定于每个受限上下文的。

Instead, a ubiquitous language is ubiquitous only in the boundaries of its bounded context. The language is focused on describing only the model that is encompassed by the bounded context. As a model cannot exist without a problem it is supposed to address, a ubiquitous language cannot be defined or used without an explicit context of its applicability.

相反,通用语言只在其有界上下文边界内是通用的。这种语言只专注于描述被有界上下文包含的模型。因为模型不能脱离其需要解决的问题而存在,所以通用语言也不能在没有明确其适用性的上下文的情况下被定义或使用。

Scope of a Bounded Context

有界上下文的范围

The example at the beginning of the chapter demonstrated an inherent boundary of the business domain. Different domain experts held conflicting mental models of the same business entity. To model the business domain, we had to divide the model and define a strict applicability context for each fine-grained model—its bounded context.

本章开头的例子展示了业务领域的固有边界。不同的领域专家对同一业务实体持有相互冲突的心理模型。为了对业务领域建模,我们必须分解模型,并为每个细粒度模型定义严格的适用性上下文——它的有界上下文。

The consistency of the ubiquitous language only helps to identify the widest boundary of that language. It cannot be any larger, because then there will be inconsistent models and terminology. However, we can still further decompose the models into even smaller bounded contexts, as shown in Figure 3-4.

通用语言的一致性只有助于确定该语言的最宽泛边界。它不能再大了,因为那样就会有不一致的模型和术语。然而,我们仍然可以进一步将模型分解成更小的有界上下文,如图3-4所示。

 

Figure 3-4. Smaller bounded contexts

图3-4.  更小的有界上下文

Defining the scope of a ubiquitous language—its bounded context—is a strategic design decision. Boundaries can be wide, following the business domain’s inherent contexts, or narrow, further dividing the business domain into smaller problem domains.

定义通用语言的范围——它的有限上下文——是一种战略设计决策。边界可以很宽,遵循业务领域的固有上下文,也可以很窄,进一步将业务领域划分为更小的问题域。

A bounded context’s size, by itself, is not a deciding factor. Models shouldn’t necessarily be big or small. Models need to be useful. The wider the boundary of the ubiquitous language is, the harder it is to keep it consistent. It may be beneficial to divide a large ubiquitous language into smaller, more manageable problem domains, but striving for small bounded contexts can backfire too. The smaller they are, the more integration overhead the design induces.

有界上下文的大小本身并不是决定因素。模型大小并不重要。重要的是它要有用。通用语言的边界越宽,就越难保持其一致性。将一个大型的通用语言划分为更小的、更易于管理的问题域可能是有益的,但是过度寻求小的有界上下文也可能适得其反。它们越小,设计所带来的集成开销就越大。

Hence, the decision for how big your bounded contexts should depend on the specific problem domain. Sometimes, using a wide boundary will be clearer, while at other times, decomposing it further will make more sense.

因此,有界上下文的大小取决于具体的问题域。有时,使用宽泛的边界会更清晰,而在其他时候,进一步分解它会更有意义。

The reasons for extracting finer-grained bounded contexts out of a larger one include constituting new software engineering teams or addressing some of the system’s nonfunctional requirements; for example, when you need to separate the development lifecycles of some of the components originally residing in a single bounded context. Another common reason for extracting one functionality is the ability to scale it independently from the rest of the bounded context’s functionalities.

从一个较大的上下文中提取更细粒度的有界上下文的原因包括组建新的软件工程团队或解决一些系统的非功能性需求;例如,当您需要分离原先位于单个有界上下文中的一些组件的开发生命周期时。提取一个功能的另一个常见原因是能够独立于有界上下文的其他功能对其进行伸缩。

Therefore, keep your models useful and align the bounded contexts’ sizes with your business needs and organizational constraints. One thing to beware of is splitting a coherent functionality into multiple bounded contexts. Such division will hinder the ability to evolve each context independently. Instead, the same business requirements and changes will simultaneously affect the bounded contexts and require simultaneous deployment of the changes. To avoid such ineffective decomposition, use the rule of thumb we discussed in Chapter 1 to find subdomains: identify sets of coherent use cases that operate on the same data and avoid decomposing them into multiple bounded contexts.

因此,请保持您的模型有用,并使有界上下文的大小与您的业务需求和组织约束保持一致。需要注意的一点是,不要将一个连贯的功能分割到多个有界上下文中。这样的分解将阻碍每个上下文独立演化的能力。相反,相同的业务需求和变化将同时影响这些有界上下文,并需要同时部署这些变化。为了避免这种无效的分解,使用我们在第1章中讨论的经验法则来查找子域:识别出一组操作相同数据的连贯用例,并避免将它们分解为多个有界上下文。

We’ll discuss the topic of continuously optimizing the bounded contexts’ boundaries further in Chapters 8 and 10.

我们将在第8章和第10章进一步讨论持续优化有界上下文边界的主题。

Bounded Contexts Versus Subdomains

有界上下文与子域

In Chapter 2, we saw that a business domain consists of multiple subdomains. So far in this chapter, we explored the notion of decomposing a business domain into a set of fine-grained problem domains or bounded contexts. At first, the two methods of decomposing business domains might seem redundant. However, that’s not the case. Let’s examine why we need both boundaries.

在第2章中,我们了解到业务域由多个子域组成。到目前为止,在本章中,我们探讨了将业务域分解为一系列细粒度的问题域或有界上下文的概念。一开始,这两种分解业务域的方法可能看起来是多余的。但事实并非如此。让我们来探讨为什么我们需要这两种边界。

Subdomains

子域

To comprehend a company’s business strategy, we have to analyze its business domain. According to domain-driven design methodology, the analysis phase involves identifying the different subdomains (core, supporting, and generic). That’s how the organization works and plans its competitive strategy.

要理解一个公司的业务战略,我们必须分析其业务领域。根据领域驱动设计方法,分析阶段包括识别不同的子域(核心子域、支撑子域和通用子域)。这就是组织如何运作和规划其竞争战略的方式。

As you learned in Chapter 1, a subdomain resembles a set of interrelated use cases. The use cases are defined by the business domain and the system’s requirements. As software engineers, we do not define the requirements; that’s the responsibility of the business. Instead, we are analyzing the business domain to identify the subdomains.

正如您在第1章中了解到的,子域类似于一组相互关联的用例。这些用例由业务领域和系统的需求定义。作为软件工程师,我们不定义需求; 这是业务的责任。相反,我们正在分析业务域以识别子域。

Bounded Contexts

有界上下文

Bounded contexts, on the other hand, are designed. Choosing models’ boundaries is a strategic design decision. We decide how to divide the business domain into smaller, manageable problem domains.

另一方面,设计有界上下文。选择模型的边界是一个战略设计决策。我们决定如何将业务域划分为更小的、更易于管理的问题域。

The Interplay Between Subdomains and Bounded Contexts

子域与有界上下文的相互作用

Theoretically, though impractically, a single model could span the entire business domain. This strategy could work for a small system, as shown in Figure 3-5.

从理论上讲,尽管不切实际,一个单一的模型可以跨越整个业务领域。这种策略可以适用于小型系统,如图3-5所示。

 

Figure 3-5. Monolithic bounded context

图3-5.  单体式有界上下文

When conflicting models arise, we can follow the domain experts’ mental models and decompose the systems into bounded contexts, as shown in Figure 3-6.

当出现模型冲突时,我们可以遵循领域专家的心理模型,将系统分解为有界上下文,如图3-6所示。

 

Figure 3-6. Bounded contexts driven by the consistency of the ubiquitous language

图3-6.  由通用语言的一致性驱动的有界上下文

If the models are still large and hard to maintain, we can decompose them into even smaller bounded contexts; for example, by having a bounded context for each subdomain, as shown in Figure 3-7.

如果模型仍然很大并且难以维护,我们可以将它们分解成更小的有界上下文; 例如,通过为每个子域对应一个有界上下文,如图3-7所示。

 Figure 3-7. Bounded contexts aligned with subdomains’ boundaries

图3-7  与子域边界对齐的有界上下文

Either way, this is a design decision. We design those boundaries as a part of the solution.

无论哪种方式,这都是一个设计决策。我们将这些边界作为解决方案的一部分进行设计。

Having a one-to-one relationship between bounded contexts and subdomains can be perfectly reasonable in some scenarios. In others, however, different decomposition strategies can be more suitable.

在某些场景中,有界上下文和子域之间的一一对应关系可能是完全合理的。然而,在其他场景中,不同的分解策略可能更合适。

It’s crucial to remember that subdomains are discovered and bounded contexts are designed. The subdomains are defined by the business strategy. However, we can design the software solution and its bounded contexts to address the specific project’s context and constraints.

至关重要的是要记住,子域是发现的,而有界上下文是设计的。子域由业务战略定义。然而,我们可以设计软件解决方案及其有界上下文,以应对特定项目的上下文和约束。

Finally, as you learned in Chapter 1, a model is intended to solve a specific problem. In some cases, it can be beneficial to use multiple models of the same concept simultaneously to solve different problems. As different types of maps provide different types of information about our planet, it may be reasonable to use different models of the same subdomain to solve different problems. Limiting the design to one-to-one relationships between bounded contexts would inhibit this flexibility and force us to use a single model of a subdomain in its bounded context.

最后,正如你在第1章中学到的,模型旨在解决特定问题。在某些情况下,使用同一概念(如地图的例子)的多个模型来解决不同的问题是有益的。就像不同类型的地图提供关于我们星球的不同类型的信息一样,使用同一子域的不同模型来解决不同问题可能是合理的。将设计限制在有界上下文之间的一对一关系会抑制这种灵活性,并迫使我们在有界上下文中使用子域的单一模型。

Boundaries

边界

As Ruth Malan says, architectural design is inherently about boundaries:

正如露丝•马兰(Ruth Malan)所言,架构设计本质上是关于边界的:

Architectural design is system design. System design is contextual design —it is inherently about boundaries (what’s in, what’s out, what spans, what moves between), and about trade-offs. It reshapes what is outside, just as it shapes what is inside.

架构设计就是系统设计。系统设计是上下文设计——它本质上就是关于边界的(什么在里面,什么在外面,什么跨越边界,什么在边界之间移动),以及关于权衡取舍。它重塑了外部世界,同时也塑造了内部世界。

The bounded context pattern is the domain-driven design tool for defining physical and ownership boundaries.

有界上下文模式是定义物理边界和所有权边界的领域驱动设计工具。

Physical Boundaries

物理边界

Bounded contexts serve not only as model boundaries but also as physical boundaries of the systems implementing them. Each bounded context should be implemented as an individual service/project, meaning it is implemented, evolved, and versioned independently of other bounded contexts.

有界上下文不仅作为模型的边界,还作为实现它们的系统的物理边界。每个有界上下文都应该作为一个独立的服务/项目来实现,这意味着它的实现、演化和版本控制都是独立于其他有界上下文的。

Clear physical boundaries between bounded contexts allow us to implement each bounded context with the technology stack that best fits its needs.

有界上下文之间明确的物理边界使我们能够使用最适合其需求的技术栈来实现每个有界上下文。

As we discussed earlier, a bounded context can contain multiple subdomains. In such a case, the bounded context is a physical boundary, while each of its subdomains is a logical boundary. Logical boundaries bear different names in different programming languages: namespaces, modules, or packages.

正如我们之前讨论的,一个有界上下文可以包含多个子域。在这种情况下,有界上下文是物理边界,而其每个子域都是逻辑边界。在不同的编程语言中,逻辑边界有不同的名称:命名空间、模块或包。

Ownership Boundaries

所有权边界

Studies show that good fences do indeed make good neighbors. In software projects, we can leverage model boundaries—bounded contexts—for the peaceful coexistence of teams. The division of work between teams is another strategic decision that can be made using the bounded context pattern.

研究表明,好的篱笆确实能造就好的邻居。在软件项目中,我们可以利用模型边界——有界上下文——有利于团队的和平共处。团队之间的工作分工是另一个可以使用有界上下文模式做出的战略决策。

A bounded context should be implemented, evolved, and maintained by one team only. No two teams can work on the same bounded context. This segregation eliminates implicit assumptions that teams might make about 2 one another’s models. Instead, they have to define communication protocols for integrating their models and systems explicitly.

有界上下文应该仅由一个团队来实现、演化和维护。两个团队不能同时处理同一个有界上下文。这种隔离消除了团队之间可能对彼此的模型做出的隐含假设。相反,他们必须明确定义用于集成其模型和系统的通信协议。

It’s important to note that the relationship between teams and bounded contexts is one-directional: a bounded context should be owned by only one team. However, a single team can own multiple bounded contexts, as Figure 3-8 illustrates.

需要注意的是,团队和有界上下文之间的关系是单向的:一个有界上下文应该只由一个团队拥有。然而,一个团队可以拥有多个有界上下文,如图3-8所示。

 

Figure 3-8. Team 1 working on the Marketing and Optimization bounded contexts, while Team 2 works on the Sales bounded context

图3-8.  团队1负责“市场营销和优化”有界上下文,而团队2负责“销售”有界上下文

Bounded Contexts in Real Life

现实生活中的有界上下文

In one of my domain driven-design classes, a participant once noted: “You said that DDD is about aligning software design with business domains. But where are the bounded contexts in real life? There are no bounded contexts in business domains.”

在我开设的领域驱动设计课程中,有一位参与者曾经提到:“你说DDD是关于将软件设计与业务域对齐的。但现实生活中的有界上下文在哪里?业务领域中不存在有界上下文。”

Indeed, bounded contexts are not as evident as business domains and subdomains, but they are there, as domain experts’ mental models are. You just have to be conscious about how domain experts think about the different business entities and processes.

确实,有界上下文并不像业务领域和子域那样显而易见,但它们确实存在,就像领域专家的心智模型一样。你只需要意识到领域专家是如何思考不同的业务实体和流程的。

I want to close this chapter by discussing examples demonstrating that not only are bounded contexts there when we are modeling business domains in software, but the notion of using different models in different contexts is widespread in life in general.

我想通过讨论一些示例来结束本章,这些示例表明,不仅在我们在软件中建模业务域时存在有界上下文,而且在一般生活中,在不同上下文中使用不同模型的概念也很普遍。

Semantic Domains

语义域

It can be said that domain-driven design’s bounded contexts are based on the lexicographical notion of semantic domains. A semantic domain is defined as an area of meaning and the words used to talk about it. For example, the words monitor, port, and processor have different meanings in the software and hardware engineering semantic domains.

可以说,领域驱动设计的有界上下文是基于语义域的词汇学概念的。语义域被定义为意义的一个领域以及用来讨论它的词汇。例如,在软件和硬件工程语义域中,monitor(监视器)、port(端口)和processor(处理器)这些词具有不同的含义。

A rather peculiar example of different semantic domains is the meaning of the word tomato.

不同语义域的一个相当特殊的例子是单词“tomato(西红柿)”的含义。

According to the botanic definition, a fruit is the plant’s way of spreading its seeds. A fruit should grow from the plant’s flower, and bear at least one seed. A vegetable, on the other hand, is a general term encompassing all other edible parts of a plant: roots, stems, and leaves. Based on this definition, the tomato is a fruit.

根据植物学的定义,果实是植物传播种子的方式。一个果实应该从植物的花朵中生长出来,并至少含有一颗种子。另一方面,蔬菜是一个总称,包括植物的其他可食用部分:根、茎和叶。根据这个定义,番茄是一种水果。

That definition, however, is of little use in the context of the culinary arts. In this context, fruits and vegetables are defined based on their flavor profiles. A fruit has a soft texture, is either sweet or sour, and can be enjoyed in its raw form, whereas a vegetable has a tougher texture, tastes blander, and often requires cooking. According to this definition, the tomato is a vegetable.

然而,这个定义在烹饪艺术的语境中几乎没有用处。在这种情况下,水果和蔬菜是根据它们的味道特征来定义的。水果质地柔软,有甜有酸,可以生吃,而蔬菜质地坚硬,味道平淡,经常需要烹饪。根据这个定义,西红柿是一种蔬菜。(我总是把西红柿当水果吃)

Hence, in the bounded context of botany, the tomato is a fruit, while in the bounded context of the culinary arts, it’s a vegetable. But that’s not all.

因此,在植物学的有界上下文中,西红柿是一种水果,而在烹饪艺术的有界上下文中,西红柿是一种蔬菜。但这还不是全部。

In 1883 the United States established a 10% tax on imported vegetables, but not fruits. The botanic definition of the tomato as a fruit allowed the importation of tomatoes to the United States without paying the import tax. To close the loophole, in 1893 the United States Supreme Court made the decision to classify the tomato as a vegetable. Therefore, in the bounded context of taxation, the tomato is a vegetable.

1883年,美国对进口蔬菜征收10% 的关税,但对水果不征税。根据植物学定义,番茄是水果,因此允许进口到美国而无需支付进口税。为了填补这个漏洞,1893年美国最高法院做出了将西红柿归类为蔬菜的决定。因此,在税收的有界上下文中,西红柿是一种蔬菜。

Furthermore, as my friend Romeu Moura says, in the bounded context of theatrical performances, the tomato is a feedback mechanism.

此外,正如我的朋友罗密欧•莫拉(Romeu Moura)所说,在戏剧表演的有界上下文中,西红柿是一种反馈机制。

Science

科学

As historian Yuval Noah Harari puts it, “Scientists generally agree that no theory is 100 percent correct. Thus, the real test of knowledge is not the truth, but utility.” In other words, no scientific theory is correct in all cases. Different theories are useful in different contexts.

正如历史学家哈拉瑞所说,“科学家们普遍认为,没有任何理论是百分之百正确的。因此,真正考验知识的不是真理,而是实用性。” 换句话说,没有科学理论在所有情况下都是正确的。不同的理论在不同的环境中是有用的。

This notion can be demonstrated by the different models of gravity introduced by Sir Isaac Newton and Albert Einstein. According to Newton’s laws of motion, space and time are absolute. They are the stage on which the motion of objects happens. In Einstein’s theory of relativity, space and time are no longer absolute but different for different observers.

这个概念可以通过艾萨克·牛顿和爱因斯坦提出的不同引力模型得到证明。根据牛顿的运动定律,空间和时间是绝对的。它们是物体运动发生的舞台。在爱因斯坦的相对论中,空间和时间不再是绝对的,对于不同的观察者来说是不同的。

Even though the two models can be seen as contradictory, both are useful in their suitable (bounded) contexts.

尽管这两个模型看似矛盾,但它们在各自合适的(有界的)上下文中都是有用的。

Buying a Refrigerator

买冰箱

Finally, let’s see a more earthbound example of real-life bounded contexts. What do you see in Figure 3-9?

最后,让我们来看一个更贴近现实的、有界上下文的例子。你在图3-9中看到了什么?

 

Figure 3-9. A piece of cardboard

图3-9  一块硬纸板

Is it just a piece of cardboard? No, it’s a model. It’s a model of the Siemens KG86NAI31L refrigerator. If you look it up, you may say the piece of cardboard doesn’t look anything like that fridge. It has no doors, and even its color is different.

它只是一块纸板吗?不,它是一个模型。它是西门子KG86NAI31L冰箱的模型。如果你查看一下,你可能会说这块纸板看起来和冰箱一点都不像。它没有门,甚至连颜色都不同。

Although that’s true, it’s not relevant. As we’ve discussed, a model is not supposed to copy a real-world entity. Instead, it should have a purpose—a problem it is supposed to solve. Hence, the correct question to ask about the cardboard is, what problem does this model solve?

虽然这是事实,但与此无关。正如我们所讨论的,模型并不是要复制现实世界中的实体。相反,它应该有一个目的——一个它应该解决的问题。因此,关于这块纸板,正确的问题是,这个模型解决了什么问题?

In our apartment, we do not have a standard entry into the kitchen. The cardboard was cut precisely to the size of the fridge’s width and depth. The problem it solves is checking whether the refrigerator can fit through the kitchen door (see Figure 3-10).

在我们的公寓里,我们没有通往厨房的标准入口。这块纸板被精确地切割成冰箱的长宽。它解决的问题是检查冰箱是否能通过厨房的门(见图3-10)。

 

Figure 3-10. The cardboard model in the kitchen doorway

图3-10  厨房门口的纸板模型

Despite the cardboard not looking anything like the fridge, it proved extremely useful when we had to decide whether to buy this model or opt for a smaller one. Again, all models are wrong, but some are useful. Building a 3D model of the fridge would definitely be a fun project. But would it solve the problem any more efficiently than the cardboard? No. If the cardboard fits, the 3D model would fit as well, and vice versa. In software engineering terms, building a 3D model of the fridge would be gross overengineering.

尽管纸板看起来与冰箱完全不同,但在我们决定是否购买这款冰箱还是选择较小的冰箱时,它证明了非常有用。再次强调,所有的模型都是错误的,但有些是有用的。建造一个冰箱的3D模型肯定是一个有趣的项目。但它在解决问题上会比纸板更有效吗?不会。如果纸板合适,3D模型也会合适,反之亦然。从软件工程的角度来看,建造一个冰箱的3D模型将是过度工程(过度设计)。

But what about the refrigerator’s height? What if the base fits, but it’s too tall to fit in the doorway? Would that justify gluing together a 3D model of the fridge? No. The problem can be solved much more quickly and easily by using a simple tape measure to check the doorway’s height. What is a tape measure in this case? Another simple model.

但是冰箱的高度怎么办? 如果底座合适,但是太高了,放不进门口怎么办?这样就能证明使用冰箱的3D 模型是合理的吗?没有。使用简单的卷尺检查门口的高度可以更快更容易地解决这个问题。在这个例子中,卷尺是什么?另一个简单的模型。

So, we ended up with two models of the same fridge. Using two models, each optimized for its specific task, reflects the DDD approach to modeling business domains. Each model has its strict bounded context: the cardboard verifying that the refrigerator’s base can make it through the kitchen’s entry, and the tape measure verifying that it’s not too tall. A model should omit the extraneous information irrelevant to the task at hand. Also, there’s no need to design a complex jack-of-all-trades model if multiple, much simpler models can effectively solve each problem individually.

因此,我们最终得到了同一个冰箱的两种模型。使用两种模型,每种模型都针对其特定任务进行了优化,这反映了DDD(领域驱动设计)在建模业务领域方面的方法。每个模型都有其严格的有界上下文:纸板验证冰箱的底部能否通过厨房的入口,而卷尺则验证冰箱是否太高。模型应该省略与当前任务无关的多余信息。此外,如果多个更简单的模型可以有效地单独解决每个问题,那么就没有必要设计一个复杂的万能模型。

A few days after I published this story on Twitter, I received a reply saying that instead of fiddling with cardboard, I could have just used a mobile phone with a LiDAR scanner and an augmented reality (AR) application. Let’s analyze this suggestion from the domain-driven design perspective.

在我把这个故事发表在推特上的几天后,我收到了一个回复,说与其摆弄硬纸板,我可以只用一个带有激光雷达扫描仪和增强现实(AR)应用程序的手机。让我们从领域驱动设计的角度来分析这个建议。

The author of the comment says this is a problem that others have already solved, and the solution is readily available. Needless to say, both the scanning technology and the AR application are complex. In DDD lingo, that makes the problem of checking whether the refrigerator will fit through the doorway a generic subdomain.

该评论的作者说,这是一个其他人已经解决的问题,而且解决方案很容易获得。不用说,扫描技术和 AR 应用都是复杂的。在 DDD 术语中,这使得检查冰箱是否适合通过门口的问题成为一个通用子域。

Conclusion

总结

Whenever we stumble upon an inherent conflict in the domain experts’ mental models, we have to decompose the ubiquitous language into multiple bounded contexts. A ubiquitous language should be consistent within the scope of its bounded context. However, across bounded contexts, the same terms can have different meanings.

每当我们在领域专家的心智模型中发现固有的冲突矛盾时,我们就必须将通用语言分解为多个有界上下文。通用语言应该在其有界上下文的范围内保持一致。然而,在不同的有界上下文之间,相同的术语可能有不同的含义。

While subdomains are discovered, bounded contexts are designed. The division of the domain into bounded contexts is a strategic design decision.

当发现子域时,会设计有界上下文。将领域划分为有界上下文是一个战略设计决策。

A bounded context and its ubiquitous language can be implemented and maintained by one team. No two teams can share the work on the same bounded context. However, one team can work on multiple bounded contexts.

一个有界上下文及其通用语言可以由一个团队来实现和维护。没有两个团队可以在同一个有界上下文中共享工作。但是,一个团队可以处理多个有界上下文。

Bounded contexts decompose a system into physical components— services, subsystems, and so on. Each bounded context’s lifecycle is decoupled from the rest. Each bounded context can evolve independently from the rest of the system. However, the bounded contexts have to work together to form a system. Some of the changes will inadvertently affect another bounded context. In the next chapter, we’ll talk about the different patterns for integrating bounded contexts that can be used to protect them from cascading changes.

有界上下文将系统分解为物理组件——服务、子系统等。每个有界上下文的生命周期都与其他上下文解耦。每个有界上下文都可以独立于系统的其他部分进行演化。然而,有界上下文必须协同工作以形成一个系统。一些更改会无意中影响另一个有界上下文。在下一章中,我们将讨论用于将有界上下文集成在一起的不同模式,以保护它们免受级联更改的影响。

Exercises

练习

1. What is the difference between subdomains and bounded contexts?  子域和有界上下文之间的区别是什么?

a. Subdomains are designed, while bounded contexts are discovered.  子域是被设计的,而有界上下文是被发现的。

b. Bounded contexts are designed, while subdomains are discovered.  有界上下文是被设计的,而子域是被发现的。

c. Bounded contexts and subdomains are essentially the same.  有界上下文和子域在本质上是相同的。

d. None of the above is true.  以上都不对。

答案:b。

2. A bounded context is a boundary of:  有界上下文是什么的边界:

a. A model  模型

b. A lifecycle  生命周期

c. Ownership  所有权

d. All of the above  以上都是

答案:d。A bounded context is a boundary of a model, and a model is only applicable in its bounded context. Bounded contexts are implemented in independent projects/solutions, thus allowing each bounded context to have its own development lifecycle. Finally, a bounded context should be implemented by a single development team, and therefore, it is also an ownership boundary. 

有界上下文是模型的边界,而模型仅在其有界上下文中适用。有界上下文在独立的项目/解决方案中实现,因此允许每个有界上下文拥有自己的开发生命周期。最后,有界上下文应由单个开发团队实现,因此,它也是所有权边界。

3. Which of the following is true regarding the size of a bounded context?  关于有界上下文的大小,下列哪一项是正确的?

a. The smaller the bounded context is, the more flexible the system is.  有界上下文越小,系统就越灵活。

b. Bounded contexts should always be aligned with the boundaries of subdomains.  有界上下文应该始终与子域的边界保持一致。

c. The wider the bounded context is, the better.  有界上下文越大越好。

d. It depends.  看情况

答案:d。There is no perfect size of a bounded context for all projects and cases. Different factors, such as models, organizational constraints, and nonfunctional requirements, affect the optimum scope of a bounded context. 

对于所有项目和情况来说,有界上下文的大小并没有一个完美的标准。不同的因素,如模型、组织约束和非功能性需求,都会影响有界上下文的最优范围。

4. Which of the following is true regarding team ownership of a bounded context?  关于团队对有界上下文的所有权,下列哪一项是正确的?

a. Multiple teams can work on the same bounded context.  多个团队可以在相同的有界上下文中工作。

b. A single team can own multiple bounded contexts.  一个团队可以拥有多个有界上下文。

c. A bounded context can be owned by one team only.  有界上下文只能由一个团队拥有。

d. B and C are correct.  B 和 C 是正确的。

答案:d。A bounded context should be owned by one team only. At the same time, the same team can own multiple bounded contexts.    一个有界上下文应该只属于一个团队。同时,同一个团队可以拥有多个有界上下文。

5. Review the example of the WolfDesk company in the Preface and try to identify functionalities of the system that may require different models of a support ticket.  回顾前言中WolfDesk公司的例子,并尝试确定系统中可能需要不同支持工单模型的功能。

答案:It’s safe to assume that the operation model, implementing the tickets’ lifecycle, will be different from the one used for fraud detection and the support autopilot feature. Fraud detection algorithms usually require more analytics-oriented modeling, whereas, the autopilot feature is likely to use a model optimized for use with machine learning algorithms.

可以安全地假设,实现工单生命周期的业务模型将不同于用于欺诈检测和自动支持功能的业务模型。欺诈检测算法通常需要更多面向分析的建模,然而,自动功能可能使用为机器学习算法优化过的模型。

6. Try to find examples of real-life bounded contexts, in addition to those described in this chapter.  除了本章所描述的内容之外,尝试找出现实生活中有界上下文的例子。


1 There is an exception here that is worth mentioning. Depending on the organization you are working in, you may be wearing two hats and be in charge of both software engineering and business development. As a result, you have the ability to affect both the software design (bounded contexts) and the business strategy (subdomains). Therefore, in the (bounded) context of our discussion here, we are focusing only on software engineering.

这里有一个例外值得一提。取决于您所在的组织,您可能同时负责软件工程和业务开发。因此,您可以同时影响软件设计(有界上下文)和业务策略(子域)。因此,在我们这里讨论的(有界)上下文中,我们只关注软件工程。

2 Bredemeyer Consulting, “What Is Software Architecture.”   软件架构是什么。Retrieved September 22, 2021, https://www.bredemeyer.com/who.htm

posted @ 2022-12-19 11:22  菜鸟吊思  阅读(71)  评论(0)    收藏  举报