领域驱动

7次阅读
没有评论

 

领域驱动设计(Domain-Driven Design,简称 DDD)是由 Eric Evans 在 2003 年提出的架构思想。

作为资深 Java 开发,你可能发现传统的“三层架构”(Controller-Service-DAO)在业务逻辑极其复杂时(如你之前参与的教育系统或交易系统),容易变成**“贫血模型”**:Service 逻辑几千行,数据库表几百个,改一个功能牵一发而动全身。

DDD 的核心就是:拒绝以数据库为中心,回归以业务逻辑为中心。


1. 战略设计:划清边界(高层视角)

在动手写代码前,先通过业务专家和技术团队的“语言对齐”,确定大版图。

  • 统一语言 (Ubiquitous Language):拒绝“程序员黑话”。代码里的变量名、类名必须和业务人员口中的名词一致(例如:教育业务里叫“排课”,代码里不能叫 TaskSchedule,而应叫 CourseArrangement)。

  • 限界上下文 (Bounded Context):这是 DDD 最核心的贡献。

    • 例子:在“订单上下文”里,User 是买家,关注收货地址;在“权限上下文”里,User 是账号,关注角色和密码。同一个实体在不同上下文中应该拆分开,避免一个 User 类变成万能补丁。

  • 上下文映射 (Context Mapping):定义不同边界之间如何通信(是通过 RPC、MQ 还是共享库)。


2. 战术设计:代码实现(落地视角)

这是你作为资深开发在 Java 工程中具体写代码的方式:

  • 实体 (Entity):具有唯一标识(ID),且状态会随时间改变。

  • 值对象 (Value Object):没有唯一标识,仅表示某种属性(如:地址、金额)。不可变性是它的灵魂,修改时直接替换整个对象。

  • 聚合根 (Aggregate Root):一组关联对象的负责人。

    • 原则:外部对象只能通过聚合根来修改内部成员。比如“订单”是聚合根,“订单项”是内部成员,你不能直接给订单项改价格,必须通过订单对象来操作,以保证业务逻辑的一致性。

  • 领域服务 (Domain Service):有些逻辑不属于任何一个实体(比如转账操作涉及两个账户),就放在领域服务里。

  • 仓储 (Repository):不同于 DAO。DAO 是对数据库表的封装,Repository 是对聚合根的持久化封装。它屏蔽了底层是 MySQL 还是 Redis 的细节。


3. 架构演进:六边形架构 (Hexagonal Architecture)

DDD 通常配合“整洁架构”或“六边形架构”使用,将核心业务逻辑保护在最里面。

  • 内层:领域模型、领域服务(纯 Java,不依赖任何框架)。

  • 外层(适配器):数据库驱动、REST 接口、消息队列。

  • 好处:如果你想把数据库从 MySQL 换成 MongoDB,或者把 Dubbo 换成 Spring Cloud,你只需要改外层的适配器,核心业务代码一行都不用动


4. 为什么资深开发都要学 DDD?

  1. 应对复杂性:当逻辑复杂到人脑记不住时,DDD 的“拆分”和“边界”是唯一的救命稻草。

  2. 微服务拆分标准:很多人拆微服务是按功能拆,结果拆成了“分布式单体”。DDD 的限界上下文才是微服务拆分的天然边界。

  3. 职业转型:正如你想做产品或架构,DDD 让你学会用业务的视角看技术,这是从“码农”向“架构师”跨越的关键。


🛠 实践建议(避坑指南)

  • 不要“为了 DDD 而 DDD”:如果只是一个简单的增删改查系统,用三层架构最快。强行上 DDD 会多出大量的 DTO、VO 转换,导致过度设计。

  • 充血模型 (Rich Domain Model):尽量把逻辑写在实体类里,而不是全部塞进 Service。让对象自己“动起来”。


📉 状态同步

  • 2026-03-29:已梳理 DDD 战略设计(限界上下文)与战术设计(聚合、实体、仓储)的核心逻辑。

既然聊到了领域驱动设计,你想看看一个标准的 Java 工程结构(例如:api, application, domain, infrastructure)应该如何组织代码吗?这能让你瞬间看清 DDD 的落地形态。

正文完
 0
bdspAdmin
版权声明:本站原创文章,由 bdspAdmin 于2026-03-29发表,共计1596字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
评论(没有评论)