我过去看过很多IT项目。其中一些设计非常好,同时也有一些非常糟糕。基于这些经验,我想写一些示例项目,我还想展示如何使用UML建模示例项目,以及如果我们将领域驱动设计原则应用于模型会发生什么。
在开始讲述本文之前,您应该阅读Eric Evans撰写的“Domain-driven Design”和Vaughn Vernon的“实现领域驱动设计”。 文中例子的大部分是基于他们的工作,如果你想深入研究领域驱动的设计,他们的书是必读的。
需求分析
一家公司提供时间出租服务。他们有一些员工,还有很多自由职业者作为分包商存在。目前,他们使用Excel工作表来管理他们的客户,自由职业者,时间表等。Excel解决方案无法很好地进行扩展。它无法应对多用户使用的场景,也不提供安全和审计日志。因此他们决定构建一个新的基于Web的解决方案。以下是核心要求:
- 搜索自由职业者分类的功能
- 用于存储联系自由职业者的不同渠道的解决方案
- 搜索项目分类的功能
- 搜索客户分类的功能
- 维护合同中自由职业者的时间表
基于这些要求,开发团队决定使用UML对所有内容进行建模,以全面了解新的解决方案。现在让我们看看他们做了什么。
架构总览
以下是他们第一次设计的情况:
这很简单。有客户,自由职业者,项目和时间表。还有一种基于角色安全的用户管理。但是等等,这里有些不对劲。 里头有一些隐藏的设计缺陷。你看得到他们吗? 缺陷如下:
- 这是一个非常大的对象图。如果他们在这里不使用Hibernate / JPA延迟加载,那么在重负载下它肯定会耗尽内存
- 为什么用户和角色之间的关联是双向的?`
- ContactType有一些布尔标志来显示它是什么类型,电子邮件,电话,移动
- Freelancer类包含Projects列表。这也意味着在不修改Freelancer对象的情况下无法添加项目。这可能会导致重负载下的事务失败,因为可能有多个用户正在为同一客户添加项目。
- ContactInformation是什么意思? 需求规定的“沟通渠道”。两者是一个概念?
整个模型似乎更像是一种全关系图而不是软件模型。另外,这是商业逻辑吗?该团队希望围绕模型创建一些商业服务来存储和检索数据,实体只是由JPA管理的POJO。
当前解决方案有很大的代码气味,一个贫血的领域模型。团队也会认识到这一点。但是什么可以解决方案呢?好吧,一位资深团队成员建议使用域驱动设计原则来为解决方案建模。好的,现在让我们看看DDD如何改进设计。
DDD的方式
在我们深入研究领域驱动设计之前,我们应该先谈谈DDD背后的原理。
DDD背后的一个原则是通过使用相同的语言来创建相同的理解来弥合领域专家和开发人员之间的差距。另一个原则是通过应用面向对象的设计和设计模式来降低复杂性,以避免重新发明轮子。
但什么是域?域是一个“知识领域”,例如公司运营的业务。域也称为“问题空间”,因此我们必须设计解决方案的问题。
好的,让我们来看看要求。我们可以认为有一个“时间租赁”领域,这是完全正确的。但是,如果我们深入了解Domain,我们会看到一些名为“Subdomain”的东西。以下子域名可能是包括以下内容:
- Identity and Access Management Subdomain
- Freelancer Management Subdomain
- Customer Management Subdomain
- Project Management Subdomain
我们可以把大问题分成小问题。这可以帮助我们设计出更好的解决方案。
分离的域可以很容易地可视化。在DDD术语中,这称为上下文映射,它是任何进一步建模的起点。
现在我们需要将子问题空间与我们的解决方案设计对齐,我们需要形成一个解决方案空间。DDD术语中的解决方案空间也称为有界上下文,并且最好将一个问题空间/子域与一个解空间/有界上下文对齐。