你应该使用领域驱动设计吗? - codeopinion


我经常阅读有关领域驱动设计如何过于复杂或过度杀伤的评论。然后还有其他新的 DDD 想要应用它,尤其是技术模式,无处不在。所以问题是,你应该使用领域驱动设计吗?答案在中间的某个地方。
 
大型系统
首先,让我定义一些我将在这篇文章的其余部分中提到的内容。在谈论系统的设计时,我指的是一个足够大的系统,它会影响组织内的许多不同角色/人员/部门。即使那个组织很小,也有不同的人在其中扮演不同的角色。
所以我在这篇文章中所指的并不是一个具有最少功能集的小型应用程序。相反,它是一个更大的系统,具有针对组织内许多不同角色的各种业务能力。
作为一个具体的例子,我将在这篇文章的其余部分使用它,假设我们正在构建一个用于送餐服务的系统。我对送餐很天真,但是,我确实有运输方面的背景,所以使用这个例子的目的是每个人都可能使用过送餐服务,所以你可能可以获得高水平。
在这个系统中,我们需要提供各种功能。我们有一些 CRM 来管理我们所有的客户,有一些类型的订单供客户下订单,HR 来管理运送食物的司机,以及从餐厅实际向客户运送食物。
  
边界
微服务带来的好处之一是承认边界。每个边界都定义了它的能力和它拥有的数据。
然而,这里的关键是并非所有边界都是平等创建的。这意味着不同的边界服务于不同的目的,在整个系统中具有不同的价值水平。
一些边界对业务域的核心更多的支持作用:CRM 和 HR 可能更多地扮演订购和交付的支持角色。根据我们的需求,支持角色的边界内没有那么复杂。因此,它们可能足够通用,您可以使用 SaaS 或 3rd 方产品,并可能与之集成。
其他一些支持边界可能不够通用,因此您必须开发它们,但它可以更多地由 CRUD 驱动,而不需要太多复杂性。
也许我们可以开发了自己的 HR 应用程序,但这只是为了保留送货司机的基本人口统计数据。
而订购和交付边界是复杂性所在,也是我们正在构建的系统的核心。
 
逻辑边界
我提到微服务带来的一件好事是边界。不幸的是,假设边界必须是物理边界并且必须独立部署。然而,重点应该首先放在简单地定义我上面所说的逻辑边界上。您不必开发微服务或可独立部署的服务。您可以开发一个由逻辑边界组成的单体。

每个边界仍然拥有自己的数据和模式。CRM 和会计是通用的,我们正在利用我们正在集成的外部 SaaS。我们不需要建立自己的会计系统或 CRM,这不是问题或解决方案的空间。
我们系统的核心可能由长期运行的业务流程组成。当客户订购食物时,我们必须通知餐厅,然后让司机拿起食物并将食物交付给客户。这是构成该工作流程的一系列业务流程。这是您关心领域驱动设计的地方。尝试对这些业务流程进行建模并在我们的代码中捕获我们领域的语言。
在支持角色的那些边界中,我们只是不需要进行太多分析来对领域的那部分进行建模。这样做没有足够的价值,因为这不是我们想要关注的解决方案空间。这些边界可以是外部的,也可以只是 CRUD。
 
能力
既然边界很重要,那么您如何定义边界是什么以及它们提供了哪些功能?
业务流程可以特定于单个边界,也可以跨越多个边界。通常,从一个边界完成其部分的越区切换从下一个边界开始。
部门和角色是考虑边界的另一种方式。您系统的最终用户在任何给定时间都可能为给定任务履行某个角色。他们想要完成什么?
边界是一种权威,有责任管理或处理流程的某个部分。
边界包含如何执行给定过程的知识。但最重要的是,它的目标是什么?它打算做什么?
 
上下文为王
如果您正在为我们的系统开发 HR 模块,是的,也许我们的送货司机的地址只是简单的 CRUD。但是,如果我们正在开发邮政/邮件服务,那么更改地址将具有更多的复杂性和过程。如果您要更改地址,是因为搬到新位置吗?是否需要邮件转发之类的东西?这根本不可能是 CRUD。在这种情况下,不仅仅是“更新地址”。这可能更像是一个需要捕捉的商业概念。上下文很重要。
CRUD如果不是特定类型的数据,例如地址、名称等,如果它是关于有关指定上下文中的数据实现增删改查,它就要值得重视。
 
你应该使用领域驱动设计吗?
如果您正在开发一个核心复杂的大型系统,那么是的,我建议您查看领域驱动设计中的一些战略(和战术)模式。如果您要围绕功能和语言(有界上下文)定义边界,猜猜怎么着?你已经在做领域驱动设计了!
如果您正在编写一个相对较小且没有太多复杂性的应用程序,请不要试图应用战术模式。