DDD 概念和面向对象

发布时间 2023-11-16 14:22:30作者: ioufev

最近了解了一些 DDD 的概念,有些解惑。

类起名和分层

首先,代码是要分类或者叫分层,放在不同的文件夹下面,一个文件夹代表一个功能。

其次,类命名和分层这件事,因为有人起名非常的随意和莫名其妙,为了规范,才有有各种理念,统一一下思想和规范。

举例,以前用户类叫 UserModel,放在 model 文件夹下,现在普遍把文件夹改成了 domain,类名换成了 User,或者UserEntity,或者UserVO。

Hibernate 流行的时候叫 UserRepository,MyBatis 流行的时候叫 UserMapper。

接口 UserService 和 实现类 UserServiceImpl 命名一直没变。

领域驱动设计

当谈论领域驱动设计(Domain-Driven Design,简称 DDD)时,这是一种软件开发方法论,旨在通过深入理解领域知识来构建复杂系统。

DDD 强调将软件开发过程与领域专家密切结合,以确保开发出更贴近实际业务需求的系统。

以下是一些关于 DDD 的关键概念:

  1. 领域(Domain):指的是软件系统要解决的问题领域,通常是业务活动所涉及的概念、规则和过程。
  2. 领域模型(Domain Model):是对领域内概念、实体、关系和规则的抽象描述。领域模型是 DDD 的核心,它有助于开发团队更好地理解问题领域,从而更好地构建系统。
  3. 限界上下文(Bounded Context):DDD 强调在大型系统中划分出多个限界上下文,每个上下文内有自己的领域模型和语言。这有助于解决不同上下文之间的概念模糊问题。
  4. 实体(Entity):领域中有生命周期并具有唯一标识的对象。实体是领域模型的核心组成部分。
  5. 值对象(Value Object):在领域中没有唯一标识的对象,它们的价值在于它们的属性。值对象通常是不可变的。
  6. 聚合(Aggregate):一组相关联的实体和值对象,构成一个边界。聚合根是聚合中负责维护一致性和边界完整性的主要对象。
  7. 仓储(Repository):提供从持久化存储中检索和存储领域对象的机制,隐藏了数据访问细节。
  8. 服务(Service):在领域内无法明确归属于某个实体或值对象的操作可以作为服务存在。服务用于跨多个领域对象的操作。
  9. 领域事件(Domain Event):领域中发生的重要事件,可以用于通知其他部分系统。
  10. 领域驱动设计的层次结构:DDD 通常分为用户界面层、应用层、领域层和基础设施层。不同层次负责不同的职责,有助于保持代码的清晰和可维护性。

总之,DDD 是一种强调在软件开发过程中理解和反映实际业务领域的方法,通过建立清晰的领域模型、划分限界上下文等方式,帮助开发团队更好地应对复杂性并构建出高质量的软件系统。

领域驱动了,领域对象模型比较重要了。

用户领域对象,该有的属性方法和事件一个都不能少,用户还要自己能改状态。

充血模型

充血模型(Fat Model)和贫血模型(Anemic Model)是软件开发中两种不同的设计思路。

充血模型是一种面向对象的设计模式,强调将业务逻辑和数据操作封装在领域模型(Domain Model)中。这意味着领域模型包含了业务规则、数据状态和操作等,它是一个功能丰富的对象,可以直接执行业务逻辑。

DDD 的历史

DDD 的基本思想是在90年代中期提出的。

它强调将领域的概念与代码紧密结合,将业务逻辑和领域模型置于核心位置。

在 DDD 中,对类的模型的关注更强调领域的本质。

有用吗

虽然 DDD 提供了一套丰富的术语和概念来表达业务领域,但在实际应用中,确实可能会造成一些与传统 Java 命名和设计方式的冲突。

这种冲突可能导致代码变得繁琐、难以理解,甚至在某些情况下增加类型转换等问题。

问题是增加了复杂性,但是并没有带来收益啊,多写了很多类型转换,强调各种难以理解的 BO DO,代码的可读性严重降低,包结构的变得杂乱。

在使用领域驱动设计(DDD)时,确保数据存储层与领域模型解耦是一个重要的原则。

在实际应用中,随时更换数据库类型确实是一项复杂的任务,基本不太可能。

感觉是在把各种业务强套 DDD,实际是业务经常变,所谓领域专家提出的模型也经常增加字段,也就是 DDD 这套逻辑似乎是用过时的概念来包装一下来套今天的业务,严重水土不服。

开发人员使用 DDD 引入了复杂性,而业务专家(也就是常说的产品)压根就不会尝试了解 DDD。

产品直接提需求,实现是开发的事情。

对比面向对象

怎么感觉 DDD 是面向对象编程的一种模块划分方式呢。

领域和 Java 中的业务对象(BO)很相似。
领域模型就是常见的 Model 类,比如用户类。
界限上下文,很像一个模块或者一个微服务,或者 k8s 中的命名空间。
实体非常像 Java 的 PO。
聚合很像网关,或者接口。
仓储很像 DAO。
服务很像 Service。
领域事件类比 Java 中的事件。
领域驱动设计的层次结构,就像 Java 编码中的常见分层。

看来看去还是 Java 编程那一套。

旧瓶装新酒

DDD 火起来主要还是微服务

综上,给类起名和分类这件事,看公司要求,或者按照常见的标准来。

因为写代码的机会可能没有看代码的机会多,看到别人起名和分层很随意,会很不爽。。