领域驱动设计示例(1)

简介: 领域驱动设计示例(1)

我过去看过很多IT项目。其中一些设计非常好,同时也有一些非常糟糕。基于这些经验,我想写一些示例项目,我还想展示如何使用UML建模示例项目,以及如果我们将领域驱动设计原则应用于模型会发生什么。


在开始讲述本文之前,您应该阅读Eric Evans撰写的“Domain-driven Design”和Vaughn Vernon的“实现领域驱动设计”。 文中例子的大部分是基于他们的工作,如果你想深入研究领域驱动的设计,他们的书是必读的。


需求分析


一家公司提供时间出租服务。他们有一些员工,还有很多自由职业者作为分包商存在。目前,他们使用Excel工作表来管理他们的客户,自由职业者,时间表等。Excel解决方案无法很好地进行扩展。它无法应对多用户使用的场景,也不提供安全和审计日志。因此他们决定构建一个新的基于Web的解决方案。以下是核心要求:


  • 搜索自由职业者分类的功能


  • 用于存储联系自由职业者的不同渠道的解决方案


  • 搜索项目分类的功能


  • 搜索客户分类的功能


  • 维护合同中自由职业者的时间表


基于这些要求,开发团队决定使用UML对所有内容进行建模,以全面了解新的解决方案。现在让我们看看他们做了什么。


架构总览


以下是他们第一次设计的情况:


image.png


这很简单。有客户,自由职业者,项目和时间表。还有一种基于角色安全的用户管理。但是等等,这里有些不对劲。 里头有一些隐藏的设计缺陷。你看得到他们吗? 缺陷如下:

  • 这是一个非常大的对象图。如果他们在这里不使用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术语中,这称为上下文映射,它是任何进一步建模的起点。



image.png


现在我们需要将子问题空间与我们的解决方案设计对齐,我们需要形成一个解决方案空间。DDD术语中的解决方案空间也称为有界上下文,并且最好将一个问题空间/子域与一个解空间/有界上下文对齐。



相关文章
|
Java Maven
SpringBoot项目如何打包、部署
SpringBoot项目如何打包、部署
320 0
|
监控 网络协议 API
阿里云BssOpenAPI是一个基于阿里云开放API的服务
【2月更文挑战第24天】阿里云BssOpenAPI是一个基于阿里云开放API的服务
586 6
|
3月前
|
存储 机器学习/深度学习 人工智能
构建AI智能体:十六、构建本地化AI应用:基于ModelScope与向量数据库的文本向量化
本文介绍了如何利用本地化部署的轻量级文本嵌入模型实现语义搜索。重点讲解了两种高效模型paraphrase-MiniLM-L6-v2和all-MiniLM-L6-v2的特点,它们通过知识蒸馏技术实现高质量语义表示,且体积小、速度快。文章详细演示了从ModelScope下载模型到本地、使用sentence-transformers库生成文本向量、构建FAISS索引进行相似性搜索的完整流程。通过Python代码示例展示了如何实现文档添加、查询处理和索引持久化功能,为构建本地化的语义搜索系统提供了实用解决方案。
662 0
构建AI智能体:十六、构建本地化AI应用:基于ModelScope与向量数据库的文本向量化
|
存储 架构师 测试技术
架构之道——人人都是架构师
本文的探讨和编写主要围绕三个方面:架构是什么?架构师要解决的问题有哪些?解决这些问题的方法论是什么?最后作者希望人人都能具备架构师思维。
|
7月前
|
存储 BI API
一文读懂数据中台和数据仓库的区别
本文深入解析了“数据中台”与“数据仓库”的区别,从定义、功能、架构设计、数据处理、应用场景等多个维度进行对比,帮助企业更清晰地理解二者的核心差异与适用场景。数据仓库重在存储与分析历史数据,服务于高层决策;数据中台则强调数据的实时处理与服务化输出,直接赋能一线业务。文章还结合企业规模、业务需求与技术能力,给出了选型建议,助力企业在数字化转型中做出更科学的选择。
1399 11
|
存储 消息中间件 NoSQL
聊一聊数据库的行存与列存
好多人最开始学习数据库的时候,是关系数据库,数据以表格形式存储,一行表示一条记录。其实这种就是典型的行存储(Row-based store),将表按行存储到磁盘分区上。 而一些数据库还支持列存储(Column-based store),它将表按列存储到磁盘分区上。
聊一聊数据库的行存与列存
|
存储 人工智能
|
缓存 Rust 前端开发
【一起学Rust | 框架篇 | Tauri2.0框架】Tauri2.0环境搭建与项目创建
【一起学Rust | 框架篇 | Tauri2.0框架】Tauri2.0环境搭建与项目创建
2275 0
|
存储 算法 安全
JVM常见面试题(四):垃圾回收
堆区域划分,对象什么时候可以被垃圾器回收,如何定位垃圾——引用计数法、可达性分析算法,JVM垃圾回收算法——标记清除算法、标记整理算法、复制算法、分代回收算法;JVM垃圾回收器——串行、并行、CMS垃圾回收器、G1垃圾回收器;强引用、软引用、弱引用、虚引用
|
缓存 算法 Java
JVM知识体系学习六:JVM垃圾是什么、GC常用垃圾清除算法、堆内存逻辑分区、栈上分配、对象何时进入老年代、有关老年代新生代的两个问题、常见的垃圾回收器、CMS
这篇文章详细介绍了Java虚拟机(JVM)中的垃圾回收机制,包括垃圾的定义、垃圾回收算法、堆内存的逻辑分区、对象的内存分配和回收过程,以及不同垃圾回收器的工作原理和参数设置。
981 4
JVM知识体系学习六:JVM垃圾是什么、GC常用垃圾清除算法、堆内存逻辑分区、栈上分配、对象何时进入老年代、有关老年代新生代的两个问题、常见的垃圾回收器、CMS