知识卡片

聚合间用ID引用而非对象引用:为未来微服务拆分解耦铺路

普通读书笔记卡

内容

聚合设计原则要求聚合之间只能通过引用聚合根ID的方式关联,而不能通过直接对象引用的方式——如果把外部聚合的对象直接放进本聚合边界内管理,会导致聚合边界变得不清晰、也会增加聚合之间的耦合度。书中给出的深层理由是前瞻性的:这样设计是为了给未来的架构演进留出解耦空间。如果领域模型随业务需求变化、微服务内需要把原本在同一个微服务里的聚合拆分到不同微服务时,原来那种聚合根之间直接对象引用的方式,在跨微服务之后会直接失效(对象引用本来就要求双方在同一个进程内存空间),届时需要付出很大的代码调整代价;而如果一开始就采用聚合根ID引用的方式,把ID作为服务调用参数进行跨聚合的领域服务调用,即使日后真的把两个聚合拆分到不同微服务里,这种基于ID的调用方式基本不需要大改,只是调用路径从同进程内的方法调用变成了跨微服务的网络调用,聚合边界本身依然清晰。这个案例给出一条通用的架构设计前瞻性原则:即使当前多个逻辑单元还部署在同一个进程/服务里,如果预见到未来有被拆分到不同物理服务的可能,现在就应该用”传递标识符、按需查询”这种松耦合的引用方式,而不是用”直接持有对象引用”这种默认假设”永远在同一个进程内”的紧耦合方式,为未来的拆分预留退路。

参考来源

- 位置:第8章《聚合和聚合根:怎样设计聚合》"8.4 聚合的设计原则"(源文件:_epub-src/OEBPS/Text/chapter3-4-4.xhtml) - 结论依据:原文说明"当领域模型随着业务需求发生变化,微服务内需要进行聚合拆分时,原来领域模型和微服务内聚合根之间对象引用的方式,就会变成跨微服务的调用,跨微服务后这种对象引用就会失效,在微服务架构演进时就需要比较大的代码调整……采用聚合根ID引用的方式……在微服务拆分时……这种代码的改动量就会小很多,聚合的边界也会清晰很多",直接支撑本卡片结论。 - 原始内容:当领域模型随着业务需求发生变化,微服务内需要进行聚合拆分时,原来领域模型和微服务内聚合根之间对象引用的方式,就会变成跨微服务的调用,跨微服务后这种对象引用就会失效……采用聚合根ID引用的方式……这种代码的改动量就会小很多,聚合的边界也会清晰很多。