前 言
如果你的用户、老板或者产品经理告诉你“这个需求很简单”,请千万不要相信。真实世界中,需要动手编程去解决的问题都不是简单的问题,你会面临业务复杂性和技术复杂性的双重挑战。首先是业务复杂性,用户一目了然的问题对你来说却是一头雾水,用户不会告诉你对他们来说是理所当然的事情,这还不算用户在提需求时可能根本没考虑周全,希望你“先出一个版本再说”。好不容易弄懂了需求(或者说以为弄懂了需求),接下来需要对付技术复杂性,这时时间已经过半,想不了那么多了,只能用自己最熟悉的框架或者参考以前做过的项目开始开发。终于出了一个版本,用户看了感觉还行(运气好的话),但是总会提出“还有几个小问题”,或者说“上次漏了几点”,希望“尽快再出一版”。这时,你会发现现有的架构已经无法支撑新增的需求。重写?一方面舍不得,另一方面“时间紧”,只好硬着头皮上。几轮循环下来,你自己清楚,软件已经摇摇欲坠了,如果再有一点新的需求加入可能就会崩溃。你已经准备离职了,只希望到新公司不要经历同样的情况。
软件的复杂性是固有的,既包括业务复杂性,也包括技术复杂性,领域驱动设计的目的在于寻求应对软件复杂性的方法。Eric Evans著名的《领域驱动设计—软件核心复杂性应对之道》这本书的书名正说明了这一点。但由于对“复杂性”的理解不同,导致很多人认为所开发的系统没那么复杂,因此没有必要使用领域驱动设计。在实践中,需要进行编程的项目都不是“简单”的:一方面由于所处的领域不同,对用户或业务专家而言是简单的问题,而对于开发人员来说往往是复杂的;另一方面,很多“复杂”的项目往往是从最初被认为是“简单”的项目演化而来的。所以说,不管在实际项目中是否使用领域驱动设计,了解相关的理论和概念都是非常必要的。
如何学习领域驱动设计?动手实践是学习软件开发的唯一有效途径,学习领域驱动设计也不例外。本书以一个读者易于理解并且具有一定弹性的项目为例,从零开始使用领域驱动设计的理论构建该项目,帮助读者从实践中了解领域驱动设计的各种概念,并提供这些概念对应的.Net实现方案。在理解概念的基础上,本书引导读者使用领域驱动设计方法构建各种类型的应用。
本书面向的读者
本书面向希望了解领域驱动设计的软件开发人员,包括刚入门的普通程序员,只要具备基本的面向对象编程基础并能使用C#编写代码,就可以阅读本书。领域驱动设计的一大主要优势在于将业务复杂性与技术复杂性分离出来:在业务建模阶段,只需具备基本的编程技能,就能够使用代码编写领域模型,而不需要对技术框架有过多的了解;在技术实现阶段,由于已经完成了领域模型的编写,因此可以更多地关注技术,而业务问题遵循领域模型即可。
本书的结构也是按照先业务后技术的顺序展开的。
本书的结构
本书分为3个部分:
第1部分介绍领域模型的基本概念、建模方法和如何验证领域模型。在这一部分中,以诗词游戏为实例介绍领域模型涉及的概念,如实体、值对象、聚合与聚合根、存储库、领域事件以及领域服务等,并使用这些概念完成领域模型的构建。另外,还介绍了如何使用单元测试和行为驱动开发工具对领域模型进行验证。最后,基于领域模型完成了简单的控制台应用。
第2部分着眼于技术实现。在领域模型中,使用接口抽象了技术实现,这些技术实现需要在基础设施层完成。这些技术实现包括:如何使用EF Core实现面向关系数据库的存储库,如何实现面向非关系数据库(如MongoDB)的存储库,以及如何实现领域事件等。
第3部分介绍如何构建各种类型的应用系统。在这一部分中,使用第1部分创建的领域模型和第2部分介绍的技术实现,根据软件架构,创建各种类型的应用,包括单体应用、前后端分离的单页面应用、桌面应用、移动应用和基于微服务的应用。最后,介绍了基于.Net的领域驱动设计技术框架ABP vNext,以及如何对系统进行提升与持续改进。
致谢
感谢同事和客户对笔者热心帮助,感谢家人对笔者的全面支持。
感谢清华大学出版社对笔者的信任和支持,感谢本书责任编辑为本书所做的工作。
反馈与交流
限于笔者的水平,书中难免存在疏漏之处,敬请各位读者批评指正。读者可以发送电子邮件至 zhenl@163.com提出意见或建议。
本书配套源码可通过微信扫描下方的二维码进行下载。如果在下载过程中遇到问题,请发送电子邮件至booksaga@126.com,邮件主题写“领域驱动设计.Net实践”。
最后,感谢各位读者选择本书,希望本书能对读者的学习有所助益。
笔 者
2023年11月