领域驱动设计 用DDD重构会计凭证生成(下)

之前写了篇如本文题目的文章 , 但考虑到篇幅就没有介绍项目的重构过程 , 今天就把这个坑填上 , 以了却一块心病 。
如果想以DDD思想为指导进行开发或重构项目的话 , 那么相关知识是必不可少的 , 所以先推荐几本DDD方面的书籍 , 从“学”开始 。
第一本当然是DDD的提出者Eric Evans的《领域驱动设计 软件核心复杂性应对之道》 , 这本花费了作者4年时间的DDD开山之作值得反复阅读 。《复杂软件设计之道:领域驱动设计全面解析与实战》 , 这本书是国内DDD布道者彭晨阳编著 , 书中实例丰富 , 对实践很有帮助 。顺便说一句 , 我非常喜欢封面上的那只黑豹 。接下来两本书都是出自  , 一本是《实现领域驱动设计》 , 这本书是对Eric那本书的丰富 , 同样值得反复阅读 。一本是《领域驱动设计精粹》 , 这本书很薄 , 可以快速带领读者走进DDD 。《领域驱动设计模式、原理与实践》这本书中的实例代码是用C#编写 , 但完全不影响作为的阅读 , 书中对DDD所涉及的所有概念从实践的角度做了阐述 , 可以作为工具书放在手边随时参考 。最后一本是Chris 的《微服务架构设计模式》 。DDD在国内的兴起与微服务被广泛的应用有着密切的关系 , 而近年来服务拆分成了导致架构师们的发量进一步减少的又一重要原因 。这本书中对DDD在服务拆分过程中所发挥的指导作用进行了介绍 。
前情回顾
之前一篇文章提到接手了一个单据审批系统 , 虽然这个系统的菜单有好几十个 , 但其实真正的核心功能只有两个 , 一个是单据审批(由实现 , 这部分需求主要集中在审批节点的维护 , 通常由业务人员在页面中即可完成) , 一个是为审批完毕或支付完毕的单据生成会计凭证 。其余功能则都服务于这两个核心功能 , 比如会计科目维护等等 。也就是说 , 这个系统的最终目的就是生成会计凭证 , 重构的便是这部分 。重构的原因在之前的一篇博客用DDD(领域驱动设计)重构会计凭证生成(上)
中进行了详细的介绍 , 总的来说就是业务扩展性差 , 且维护与测试难度都比较大 。
凭证的生成依赖于“凭证生成规则” , 重构前的凭证生成是先根据单据的类型等属性从数据库中获取已配置好的规则记录 , 然后依照所匹配的规则创建凭证 。重构前代码结构如下图所示 。
为拆而拆的微服务
如上图所示 , 该系统在重构前最大的问题是凭证生成这个最核心的业务逻辑分散在了门面和凭证两个微服务中 , 也就是说 , 要想修改或新增一条“凭证生成规则”就必须同时修改上述这两个微服务并进行发布 。Bob大叔曾在其《架构整洁之道》中提出CCP(共同闭包原则) , 简单的说就是一个组件的修改只能由一个原因引起 , 或者说我们在设计时就应尽量将可能被共同修改的元素集中到一个组件中 , 从而为发布、验证和部署提供便利 。虽说在如今 , K8S , 等一众工具的加持下 , 别说上面才两个微服务 , 即使同时发布若干个项目也只需在页面上轻点按钮便可完成 , 难道坐拥如此的便利就可以想当然的拆分服务了 。类似凭证微服务这样 , 为了标榜自己是由一堆微服务组成的系统而拆分出的微服务还有好几个 , 例如支付微服务(专门对接支付系统 , 当需要对接新的支付接口时也需要同时修改门面和该支付微服务) , 编号微服务(为单据生成业务编号)等 , 这些微服务其实都能以模块的形式集成到门面服务中 , 可它们全部被拆分成微服务 , 好像不拆分成微服务就对不起 boot;不经过一次Http调用就愧对于天下 。这种为了拆分而拆分 , 很像.U- .S- .A-的-政#治$正^确 , 只要拆分了就是好的 , 不管是否合理 。