DDD是领域驱动设计的简称,与MVC三层架构不同,DDD是一种建模方法论。
很多人初次接触DDD会有些反感,特别是对DO、DTO、PO这些对象转来转去反感,也有人质疑这样做影响性能。
笔者在《汇编语言程序设计》这本书中看到一段话,觉得很适合回答各位的这个问题:既然使用解释语言会降低速度,为什么还有人仍然要使用它们,是因为便利。
没错,就是便利。相比于高度耦合的代码,使用经典DDD四层架构设计,能够让代码具有更高的移植性、可读性和扩展性。使用DDD建模方法,能够划分出更清晰的业务边界,也更适合用于拆分微服务。
但这句话并非说我们就不追求性能了,这不冲突。既然对象转换是必然,我们可以在必然的事情上考虑性能,就如同工作要作,但使用插件能提升开发效率。
不同于MVC,DDD是一种方法论,既然就是理论性的知识,所以我们才会感觉DDD难学,这让很多人望而却步,也让很多人在DDD领域中摸不着北。
(笔者认为,DDD的难点在于领域边界的划分。)
正因为这样,笔者目前也并不打算写DDD方面的文章,因为笔者也是入门级别的水平,除非在有丰富的实战经验后,才敢放言DDD。
但为什么我却如此急着使用DDD去重构才刚上线的新项目?
一个关键词是“新项目”,是理论运用到实际项目中的机会。新项目试错成本低,因为这个新项目只是从旧项目中刨离出来的项目。
新项目没有历史包袱,并且从技术选型到架构设计都由笔者主导,笔者对项目整体架构非常熟悉,也就有足够的信心去试错。
最后,迫使我们急切想要尝试DDD的原因,就是因为我们看到了传统MVC三层架构的一些弊端,而DDD正好可以解决。
首先聊聊我们在使用MVC三层架构中看到的一些痛点。
1、Service层过于臃肿,所有业务代码主要集中在Service层中。
并且很多人习惯使用一条非常复杂的SQL去解决一个复杂的业务问题,在他们看来,处理业务不就是增删改查吗,能用一条SQL解决的事情为什么要用两条?如果只是简单的增删改查,其实也可能不适合使用DDD。
我们容易写着写着,就将多个业务代码耦合到了一起,一个表对应一个Service,没有所谓的按业务分不同的Service,Service变成是数据库表驱动的了。
笔者在前面一篇文章也吐槽过,Mybatis Plus的代码生成器插件竟然默认为一个Mapper生成一个Service。
2、三层之间紧密偶合,业务边界不清晰。
笔者从自己经历过的多个项目中发现,一个MVC架构还能有多种风格。
比如,没有Service层,只有Controller和DAO的;比如,虽然有Service,但Service仅仅只是DAO的一个委托,业务逻辑还是在Controller层实现的;再有就是DAO查询的数据直接响应给前端的。
当然,并不是说使用DDD后就能统一风格,为了更好的适应团队,综合团队对DDD的接受程度,也会存在多种风格,但不存在像MVC那样大的差异。
综合以上两点,当项目变得臃肿后,都难以实现代码直接复用,将部分功能拆分出来。业务边界不清晰也会导致拆分微服务有众多的争议,争议着、争论着,最后谁也说服不了谁。
在《实现领域驱动设计》这本书中,有一句话我们不得不承认,因为以往我们也都是这么做的,以上两点很好的证实了。
“我们曾趋向于将关注点放在数据上,而不是领域上。”
因为在软件开发中,数据库依然占据着主导地位,所以我们自然而然的优先考虑数据的属性和关联关系,而不是考虑富有行为的领域概念。
让我恍然大悟的还是这句:“我们将太多的投入放在开发数据库表编辑器上。”
“开发数据库表编辑器”!
不是吗?我们以往和现在写的很多代码,不就是实现一个数据库表的编辑器吗?
那么,使用DDD建模、重新架构设计后,能够带来哪些好处?
1、我们将业务边界划分清晰了,业务代码与基础框架也更松耦合了。
2、只要领域模型设计得当,便易于微服务的拆分。为什么说便于微服务的拆分,我们看第三点。
3、应用层根据行为去组合调用领域方法实现跨多个业务的功能,领域层只专注于业务边界内的业务代码的实现。领域层的业务代码复用性更高。
当需要将某块业务抽离为微服务时,应用层只需要将原本调用该业务的领域方法改为通过基础架构层去调用被抽离的这块业务的微服务接口。
4、我们可以先不用去考虑如何设计数据库表,而应该是在聚合实体类确认后再去设计数据库表。一个实体类最终持久化到数据库,可能需要设计两个或者多个表去存储。
关于微服务拆分每个人的见解都不同,在团队中意见也很难达成一致,而使用DDD建模后,就很容易根据领域模型拆分和重组微服务。
DDD更适合处理高度复杂的业务场景、适用于微服务,也适用于复杂的单体项目。
DDD核心思想是通过领域设计定义领域模型,不会考虑代码如何去实现,对于如何实现也没有统一的做法,也不会考虑DO、DTO、PO之间相互转来转去多麻烦、对性能影响又如何。
代码是写给机器执行的,却是写给人看的。有时侯,我会为了可读性而牺牲一点性能,也会为了扩展性而多写些代码。
代码无疑是一种艺术,每个人对艺术的见解都不同,因此,我们很容易达成一个共识:别人写的代码永远没有自己写的六。
除了使用设计模式外,架构设计也非常的重要,这是项目的地基。很早之前就感觉MVC这种风格与我追求的艺术格格不入,直到了解到DDD,有种相见恨晚的感觉。
最后,借用《实现领域驱动设计》作者那句话:并不是所有项目都适合使用DDD!