写了好几章的东西,再回头读的时候发现有些内容写的不理想,没有表达出自己所想要表达的意思。这次写一个补遗,把我认为需要重新解释和着重说明的内容再唠一唠。反正我多说两句,您就可以多理解一些。按此等形式,我感觉下次应该找个小弟当副编辑,专门用于挑错。废话不多说,走起……
一、为啥我讲的和书上的内容有些不一致?答:四个原因。1,“尽信书,不如无书”,这是这么一个简单的道理。《领域驱动设计:软件核心复杂性应对之道》及《实现领域驱动设计》这两本书可以说是一脉相传,都是针对复杂的业务给出的解决方案,书中针对战术模式的讲解力度很大尤其是后面这本。我所讲的自然要基于经典,实际上也没有超出它们的圈子,只是里面加入了一些我的理解,这些理解主要是源于工作实践以及自己的思考。我期望找到一种更为朴素的方式来表达各种模棱两可的概念,给它们一个明确的定义,这些问题是过去我在学习中碰到的障碍,所以您各位别整天惦记着看代码,没有理论的指导代码也好不了哪去,老马说什么来着?对,“理论与实践相结合”。另外,我喜欢在工作中总结和发现一些模式,“人剑合一”不是武功的最高境界,创造武功才是;2,大部分书上所讲理论色彩较浓,这是写书的基本要求,要是着边就是各种漏洞那岂不是找着被人怼?写博客要相对随意一点,只要读者能明白就齐了,不过随意不等于写的东西漏洞百出,这就是坑人了;3,看过很多的书后,理论积累了不少但在落于实践的时候仍然困难重重,这是个人亲身体验,也说明了理论与实践中存在着差异。代码设计与研发是较偏向于实践的工作,可在实践过程中却又没有严格的标准供参考。所以我在试图找出一种以实践证明理论的方式来加强学习者对于理论的理解;4,都和别人的一样,我的这个系列文章就没有存在的价值了, 那我还写个毛线啊。
二、BC的划分是否有标准?答:无标准。这东西的划分主观因素占据的较多,“一千人眼中有一千个哈姆雷特”,不信你找两个技术差不多的人对同一个系统做BC分割,绝对不一样(只要是正常的人,不一样的情况多数也只体现在细节上,大块上的分割也差不不多少)。话虽如此,还是有一些指导性的原则可供使用:1)按业务能力划分;2)按单一责任原则划分;3)按业务流程划分;4)按非功能性需求如性能、数据量、系统更迭速度等。BC是DDD中最为核心的内容,通过子域进行推演而出并为领域模型限定了工作空间。不严谨的说,DDD中的大部分概念包括通用语言、战术模式都几乎是以BC为单位的。
三、事务脚本到底是不是对DDD的误用?答:当然不是了。事务脚本是指面向过程编程,使用经典的三层模式,业务代码集中于应用服务中,一个过程一个过程的编写代码,属传统的编程模式。而DDD中最为核心的部分是战略,使用战略思想指导系统的建设从起点上就是正确的一大步。系统一般都会存在着大量的基于保存、修改、查询等简单业务的微型服务,此时使用事务脚本非常有利于推动项目的前进速度及团队管理者对于资源的分配。把高级或专家级开发都分配到业务简单的模块,把初级开发放到强逻辑服务的上面,相信没有哪个领导会这么傻。是否应用DDD并不看使用了哪种模式对代码进行落地,而是看你在战略上所采用的DDD思想的多寡。这也是一个渐进的、不断学习的过程,哪怕最初您只用到了10%的DDD理论作为系统建设的指导依据也是一个巨大的进步。任何一个系统都不会是一成不变的,在变化中灵活的、有取舍的使用DDD才是使用正确的姿势。
四、DDD和微服务架构什么关系?答:一对好基友。我觉得微服务架构是DDD的最佳实践,尤其是在战略上面:微服务架构中的每一个服务都对应了一个DDD中的BC;BC的设计可以指导微服务架构中服务的划分。在我初学DDD的三四年里,当时理解度很不够,但仍能觉得分出这么多BC后,服务的运维、部署、研发的难度一定会巨大。有的时候一个业务跨多个BC,仅就部署的工作就是个大的难题。可以这么说,DDD出来之时就是一种跨时代的产物,您所能实践的并不多。而随着容器、微服务框架等技术的发展,DDD才有了发挥的空间。
五、单体架构是不是违反了DDD思想?答:不存在这个概念。单体与微服务架构是两种不同的架构风格,具体您使用什么系统与系统的需求、公司的组织结构、资源配给、技术积累等有着巨大的关系。虽然DDD推崇使用微服务架构,但当条件达不到时不要勉强。还是那句话,DDD思想的重要性要大于某一个具体的战术模式。我见过一些写微服务架构技术的文章,极力反对单体甚至将其鄙视的猪狗不如,这种态度就太扯犊子了。微服务架构的确先进,那东西也有它的局限性的。有一次面试,面试官大力的炫耀:我们这儿,每个接口都是一个服务。说这种话的人一般也是近亲结婚的产物,一笑置之即可。有这样一种理论我觉得有点意思:微服务架构能实现服务间的解耦,对应的组织结构也需要进行调整以实现微服务研发团队间的解耦,只有两者匹配时才能实现生产力的最大化。我觉得这话老有道理了,这几年被部门墙和团队墙折磨的着实够劲儿。
六、BC的作用到底有哪些?答:三个作用。1,系统部署的基本单位,BC对一个大系统在物理结构上进行了划分尤其在使用微服务架构落地时效果更为明显。以BC为单位,大的系统被分割成物理上独立的、可单独部署的小服务,仅就其隔离作用所带来的优势也是单体不具备的;2,确认了领域术语,让每个业务概念在BC中的含义是明确的、精准的;3、为领域模型划分了作用边界,避免出现超级类。比如电商中的“用户”概念,在“订购”BC中主要关注会员、优惠等级等与订购活动相关的属性;在“物流”BC中主要关注地址、联系方式等与收货、物流相关的属性;在“营销分析”BC中会关心其购买记录等信息;在“账户管理”BC中主要关心其基本属性的录入、管理等;在“支付”BC中则需要关注其账户余额、交易流水等。如果没有BC的隔离,您可能就需要建立一个巨大的类包含:地址、优惠等级、联系方式、购买记录、商品评价、账户金额等全量的信息。存储一个客户信息搞不好需要建立一个包含100+字段的表,现实中我遇到过这种情况,没人敢接手代码维护。
七、子域、BC等划分出错是否会严重影响系统的建设质量和速度?答:影响不大。虽然BC的划分有一定的主观性,但干这个事情的人都有一定的经验,即使没有也可以简单的根据业务能力划分出来。很多问题其实都是随着系统的使用出现的,随时根据需要对BC进行调整,让BC的变更与系统的需求演进保持同步,划分会越来越贴近您所谓的“正确”。这种不停的对代码进行重构是一种对工作负责的态度,如果您的团队中有这样的人就加紧用好了,好的代码都是通过多次的调整才出来的。
八、本系统文章后面还有哪些内容?答:除了一般DDD书中所讲的战术部分,还会讲一些开发过程中常见但很容易使用不当的内容包括验证、日志管理等。此外,还会引入一些实际的案例进行演示。同前面的内容一样,白话居多。另外再多提一句:别着急看代码,好多理论我自己都琢磨了好久,那都是金不换的。