笔记-重构改善饿了么交易系统的设计思路

3次阅读

共计 2157 个字符,预计需要花费 6 分钟才能阅读完成。

本文是《重构:改善饿了么交易系统的设计思路》的读后笔记, 部分文字摘自原文。文章思路与笔者近半年的实践十分贴近,叙述非常系统,且有极其扎实的实践案例支撑,具有深刻指导意义。这里只是笔者整理的大纲用于个人归档。十分建议直接跳转原文阅读。

1. 重构的思路

进行系统设计时,摸清楚目的,并形成可衡量的目标是第一步
系统设计的目的 -> 系统设计的目标 -> 围绕目标的核心设计 -> 围绕核心设计形成的设计原则 -> 各子系统,模块的详细设计

2. 升级架构的原因

  • 业务持续不断的差异化定制,
  • 并行上线的要求。
  • 随着公司组织架构变化,有的项目需要多地协同推进才能完成,沟通协作成本翻倍提升。

几方面结合起来,导致开发没有精力对大部分系统的演进都进行完善的规划

一个简单需求,开发评估下来的工作量远远超出了预期,业务方对此不满意。但实际上,团队里没人偷懒,只是不管投入了多少个人时间,救了多少次火,加了多少次班,产出始终上不去,因为开发大部分时间都在系统的修修补补上,而不是真正完成实际的新功能,一直在拆东墙补西墙,周而往复。大部分系统已经演变到很难响应需求的变更了,业务认为的小小变更,对开发来说都是系统的一次大手术

采用好的软件架构来节省项目构建和维护的人力成本,让每一次变更都短小简单,易于实施,并且避免缺陷,用最小的成本,最大程度地满足功能性和灵活性的要求

3. 解决方案

3.1 Source code is the design

指出了详细设计的重要性,同时详细设计会显著的影响顶层设计。表达了系统不应该完全的自顶向下设计的思想。

高层结构的设计不是完整的软件设计,它只是细节设计的一个结构框架。在严格地验证高层设计方面,我们的能力是非常有限的。详细设计最终会对高层设计造成的影响至少和其他的因素一样多(或者应该允许这种影响)。对设计的各个方面进行改进,是一个应该贯穿整个设计周期的过程

同时原文认为

“系统设计应该是从下到上,随着抽象层次的提升,不断演化而得到良好的高层设计”

这符合很多著作中对设计的描述,如 R.C Martin 在《敏捷软件开发》中指出“不要为不存在的需求提前做出设计”,但是笔者认为先做一定的高层设计是十分必要的,这样可以避免在错误的时间意外的扎入细节中。

3.2 编程范式

作者首先论述了其对多种语言的抉择过程,Python 的速度优势对项目初期的帮助、Go 语言简单的语法是如何降低初级程序员的出错率、成熟后使用 Java 重构带来的整体稳定性和可维护性的优势。

接着论证了面向对象编程(OOP)的重要性,并证实了 (Spring) 企业开发过程中面向过程(OPP)的编程是有优势的,并以业务流程的天然过程性为例。笔者十分支持这种观点,面向对象设计与设计模式会使程序呈现立体的结构,代码不再是一个平面内的顺序阅读过程,这会增加理解的复杂度。在企业开发中,需要根据业务代码的复杂度与数量,在使用模式和 OOD 增强代码的维护性,或使用 OPP 增强代码的易理解性间做出平衡。

作者认为

编程范式也许是学习任何一门编程语言时要理解的最重要的术语,简单来说它是程序员看待程序应该具有的观点

并确认

采用以 OOP 为主的“混合”范式,因为合理运用 OOP 的设计思想已经被证明确实可以支撑起复杂庞大的软件设计

3.3 原则和模式

3.1 陈述了顶层设计应遵循的风格,3.2 陈述了实际处理的范式,本节则回到两者之间,描述了开始详细设计时的指导理论和结合大量实践的解释。

  • 包括 OOD 中的设计目标 SOLID 原则
  • 设计模式的应用,同时支撑 3.2 的思想,指出了不应该一味的套用模式。其选用的案例:在处理订单和不同状态的代码中,使用状态模式替代大段 switch 语句,避免了对 OCP,和 SRP 原则的直接破坏,增强维护性和稳定性。再指出这种订单系统中最常见的处理手法的缺点,state 类的膨胀带来的复杂度,状态机本身对 OCP 的违反,以及最重要的“整个状态机的逻辑隐藏在零散的代码里”,然后给出了另一种指导性的面向过程的解决方案“解释迁移表”,非常适合规模中等的状态机,并指出了当状态管理达到一定程度后,仍应该选择流程引擎等方案管理状态。并再次强调了“不能设计模式驱动编程”

3.4 DDD 领域驱动设计

再完成设计层面的思想介绍后,理所应当的论述了 DDD 的优势,DDD 的关键优势在于连接了分析与设计这两者,提供了一致的工具。整合整个团队,使业务、产品与技术使用相同的“语言”,极大的降低了团队沟通成本,这使得 DDD 不仅仅作为一项 IT 技术而被应用。

原作本节有大量基于深度实践的对 DDD 的解释,

同时其中对 CQRS 的解释对于笔者具有指导意义,即 CQRS 不一定需要整套体系一起上,一个业务层的单独的模块 / 系统,跳过领域层和其平行访问基础数据层,这样的结构本身就能在架构上带来大量的优势。

即,笔者认为

  • 业务服务中,写操作(命令)的数量远远低于读操作,大量的查询服务会使领域服务膨胀,降低可读性与稳定性。
  • 单个 Query 对性能消耗很可能高于 Command,而为了维持 OOD 使用的 ORM 架构通常不够高效。
  • Query 经常需要跨领域 / 边界,将 Query 视作常规领域服务会在设计上造成大量耦合
  • 在笔者的项目中还有 Query 可以使用操作数据更方便的非 Java 语言的优势

所以读写分离后领域服务的维护性将大幅提升。

结语

No Silver Bullet
个体和交互胜过过程和工具

正文完
 0