DDD是应对业务复杂的的方法论,有战略设计和战术设计两大块。
战略设计的核心是统一语言和限界上下文,战术设计的核心是独立领域逻辑层。
其实解决一个复杂领域系统的方式不只限于编码架构,我们同样需要从一些外溢的环节去考虑应对这种复杂度。
复杂系统设计为什么复杂?可以从软件开发过程,复杂系统设计,模块编码角度看。
首先说软件开发过程
如果一个领域过于复杂,我们一般会将能力分散到多个团队,也就是说往往一个复杂的领域实现是由多个子系统、子服务、子团队组合去实现的,那么如何提高跨团队的沟通效率,确保沟通与传达内容的一致性就很有必要。
在软件开发中有这样两个理论:
- 软件开发过程中的技术知识通过分工建立知识壁垒来提升效率
- 软件开发过程中的业务知识需要消除知识壁垒才能提升效率
各岗位专业度的提高,分工是必然的,那么怎么解决业务知识传递问题, DDD的一个核心模式是统一语言,用于解决解决业务知识传递的问题。有了这样的统一沟通语言,对于事务统一的定义和描述,帮助我们在需求定义、问题定义方面起到了很好的沟通效率和沟通效果。
统一语言有两个含义。
1、统一交流语言。
我们把业务名词的含义事先确定好,在业务和技术的各个岗位都统一认知,这样在交流时,由于对业务名词的理解已经同频了,会节省很多沟通成本。
2、统一领域模型和代码模型。
一个系统最重要的知识沉淀就是代码和文档了,当然很多公司都没文档,当业务模型和代码模型一样,会大大降低我们系统的认知复杂度。如果不一样会让大家懵逼掉。
其次是复杂度设计
为了降低业务系统复杂性,一般是通过分而治之的方式,现在流行的微服务就是基于业务维度进行拆分,那么到底怎么拆分。
分治思想是应对软件复杂度设计很重要的一种方法论,因为不同阶段、面向不同用户的系统他的复杂度来源不同,有的来源于业务的快速变化,有的来源于高并发场景下的技术复杂度挑战,有的来自于数据规则,有的来自于业务规则,有的来自于系统边界不清晰导致多个研发团队共用一套代码或系统。
最简单的方式就是分治策略,将业务复杂度,技术复杂度等,不同复杂度问题拆解处理,各自独立治理,起到最终解决复杂度问题。
比如我们做中台系统其实就是一步步分治的过程,将功能性与非功能性的能力分出来,将基础能力与商业能力分出来,将易变的与不变的分离出来。
开发复杂企业业务系统所需要的领域数据模型、逻辑&服务编排、专业UI页面设计等,都可以在一体化的低代码开发平台上实现。
领域驱动的设计思想提出了一个很好的出发点,区别于传统基于数据库表设计系统底座的方法论,领域驱动要求,围绕于业务边界及业务上下文展开。
如下图,每个点代表一个领域对象,当很多个对象混合在一起时,设计者或者开发者需要了解所有领域对象,无疑增加了复杂度。如果能找到一种方式合理划分边界,让联系紧密的对象聚合在一起(比如下图中形成ABC三个聚合),聚合之间通过接口交互,那么接口数量会是最少的。DDD的限界上下文提供了一种指导思路,限界上下文划分好后,一个限界上下文可以对应一个微服务。
这里同样运用了建立知识壁垒可以提升效率这个理论,开发A服务的人实际上不需要了解B服务的内部实行,只需要了解B提供的接口即可,A服务的领域对象数量已经大大下降了,无疑降低了复杂度。
再说下编码实现
传统的三层结构是web,service,dao。当一个系统变复杂了,如果不加以约束,一个service类达到上万行,维护起来及其痛苦。
解决service层大泥球的一个方法是分离复杂性,把service分为应用层和领域层。背后的设计原则业务和技术分离。领域层放业务逻辑,应用层放技术逻辑,复杂性降低,并且领域层更便于测试。
DDD战术设计就是把业务逻辑放到最核心位置,整洁架构和六边形架构也是如此,跟业务相关的代码写到实体,值对象和领域服务里面,一些事务,缓存等技术相关代码写到应用服务里面。
举个例子
购物车有个操作是添加商品到购物车,应用层ShoppingCartApplicationService把事务,缓存处理掉,核心业务逻辑在ShoppingCart这个领域对象里面。
领域层代码如下:
应用层代码如下:
当然将DDD在系统落地,还是需要对于系统及系统所支撑的业务有比较深的了解之后才可以进行,毕竟大部分的场景我们还是在做逐步重构,而不是从零到一直接搭建,重构就是有历史包袱。
可能需要熬几个晚上,把领域建模,业务架构大部分的资料,代码,核心内容都看完,感受顿悟。在拉上相关同学从DIP讲到SDP,从DDD讲到clean architecture,从数学模型推出分层和反转的基础,把洋葱模型、六边形模型包在同一个推导之下,输出一个正规可落地的方案才是正道。
写在后面
DDD的统一语言在软件开发过程中能帮助业务知识更好的传递,限界上下文能指导复杂系统的拆分,战术设计能帮助代码更好的分层。但DDD提供一套方法论,一个指导思想,也不是必须全部用上,完全可以只借鉴其中一部分。比如DDD的统一语言是通过降低业务知识的传递提升效率,可以应用到实际开发中。方法论能提供指导,但也不要生搬硬套,需要根据自身情况进行裁剪,灵活运用。