# 一. Introducing Domain-Driven Design

DDD 社区指导我们如何创建通用的模型:

• 关注业务事件和工作流程, 而不是数据结构 (ps: 职责驱动)
• 将问题域划分为较小的子域
• 为每个子域创建解决方案模型 (Bounded Contexts – Domain Model)
• 开发一种公共语言在项目涉及的每个人之间共享, 并在代码中随处使用

# Understanding the Domain Through Business Events

DDD 收集需求的方法强调在开发人员和领域专家之间建立共识, 但是我们该从哪开始?

## Discovering the Domain: An Order-Taking System

“我们是一家小公司, 为其他公司制造零件: 小部件, 小物件等. 我们发展非常快, 我们的现有流程无法跟上. 目前, 我们所做的一切都是基于纸张的, 我们希望将所有这些都让计算机进行处理, 以便我们的员工可以处理大量的订单. 特别是, 我们希望拥有一个自助服务网站, 以便客户自己完成一些任务. 下订单, 检查订单状态等.”

• 通用的业务模型. 每个人都在同一堵墙上看到相同的东西
• 更好的团队协作. 所有的团队都参与到讨论, 有可能你的输出会是另一个团队的输入, 所以你可能需要了解的更多
• 发现缺省的需求. 在项目开始时需求通常很模糊, 随着讨论的深入, 一些需求会慢慢浮出表面

## Expanding the Events to the Edges

"是什么触发了 Order form received 事件?"
"我们每天早上打开邮件, 客户会发送订单表格过来, 我们将其分类为订单或报价."


"将订单运送给客户后, 是否有可能发生的事件?"
"如果订单是[已签收交货], 我们将收到快递服务的通知, 那么我添加一个 Shipment received by customer 事件"


# Partitioning the Domain into Subdomains

Getting the Contexts Right 介绍了其它的一些帮助准则.

# Creating a Solution Using Bounded Contexts

## Getting the Contexts Right

DDD 的最重要挑战之一是正确设置这些界限上下文. 以下是一些帮助准则:

• 观察领域专家. 如果他们使用相同的语言并专注于相同的问题, 则他们可能在属于同一个领域(映射到界限上下文).
• 注意现有团队/部门的界限. 这些是企业认为的领域/子域(映射到界限上下文)的有力线索. 当然, 这并不总是正确的, 有时同一部门中的人们彼此之间工作不一致; 相反, 可能会有不同部门中的人员紧密合作, 这反过来意味着他们可能在同一领域工作.
• 不要忘记 “界限”. 我们需要明确界限上下文中的 “界限”, 特别是在需求不断变化时. 太大或太模糊的边界相当于根本就没有边界. (当然, 我们也有专门处理需求变化的方案, 在后续会详细介绍)
• 自主设计. 如果两个小组对相同的界限上下文做出贡献, 那么它们可能会朝着不同的方向发展. 这会造成设计越来越混乱. 所以, 相比于试图让每个人都感到高兴的大型上下文, 可独立发展的并且有界限的上下文总是更好.
• 为更流畅的业务工作流服务. 如果工作流与多个界限上下文进行交互并且经常被它们阻塞或延迟, 请考虑重构界限上下文以使工作流更加流畅, 即使设计变得 “难看”. 也就是说, 始终专注于业务和客户价值, 而不是任何一种 “纯” 设计.

## Focusing on the Most Important Bounded Contexts

PS, 区分支撑域以及通用域可能并不那么重要, 但是识别出核心域还是蛮重要的, 因为核心域会让我们花更多的财力, 人力在上面.

# Summarizing the Concepts of Domain-Driven Design

We’ve been introduced to a lot of new concepts and terminology, so let’s quickly summarize them in one place before moving on.

1. A Domain is an area of knowledge associated with the problem we are trying to solve. Alternatively a “domain” is that which a “domain expert” is expert in.
2. A Domain Model is a set of simplifications that represent those aspects of a domain that are relevant to a particular problem. The domain model is part of the solution space, while the domain that it represents is part of the problem space.
3. The Ubiquitous Language is a set of concepts and vocabulary associated with the domain, shared by both the team members and the source code.
4. A Bounded Context is a subsystem in the solution space with clear boundaries that distinguish it from other subsystems. A bounded context often corresponds to a subdomain in the problem space. A bounded con- text also has its own set of concepts and vocabulary, its own dialect of the Ubiquitous Language.
5. A Context map is a high-level diagram showing a collection of bounded contexts and the relationships between them.
6. A Domain Event is a record of something that happened in the system. It is always described in the past tense. An event often triggers additional activity.
7. A Command is a request for some process to happen, triggered by a person or another event. If the process succeeds, the state of the system changes and one or more Domain Events are recorded.

# 附: 事件风暴

• You: “Someone start by posting a business event!”
• Ollie: “I’m Ollie from the order-taking department. Mostly we deal with orders and quotes coming in.”
• You: “What triggers this kind of work?”
• Ollie: “When we get forms sent to us by the customer in the mail.”
• You: “So the events would be something like ‘Order form received’ and ‘Quote form received’?”
• Ollie: “Yes. Let me put those up on the wall then.”
• Sam: “I’m Sam from the shipping department. We fulfill those orders when they’re signed off.”
• You: “And how do you know when to do that?”
• Sam: “When we get an order from the order-taking department.”
• You: “What would you call that as an event?”
• Sam: “How about ‘Order Available’?”
• Ollie: “We call an order that’s completed and ready to ship a ‘Placed Order.’ Can we agree on using that term everywhere?”
• Sam: “So ‘Order Placed’ would be the event we care about, yes?”

You get the idea. After a while, we might have list of posted events like this: