流程是易变的、脆弱的,对象是稳定的、高内聚的。面向对象的流程是分治,将易变的流程拆分成多个稳定的对象,对象之间面向接口协作,复杂性拆分成局部复杂性。
现象
我们 iaas 很多代码都是面向过程,而架构上也有很多是面向过程,而没有面向对象。
比如创建主机,存储资源没有抽象,全都是在过程中各种条件判断来处理的。其实需要的是一个存储系统、存储对象。
创建备份也是一样,创建备份和存储备份耦合在一起,没有区分。
存储备份完全是面向过程,写了两个流程:
- rsync 上传到 snapshot;
- snapshot 之间复制副本。
其实创建备份和存储备份完全是独立的两个事务,而且是差别很大的两个事务。
很明显,存储应该是一个独立系统,是一个存储对象。
我们需要的是面向对象,过程应该是在对象内的。
核心:对象是骨架,流程是血肉
- 流程是易变的、脆弱的,编排流程;
- 对象是稳定的、高内聚的。
最终:
- 面向过程的流程,是一个大的、长的、前后依赖的、复杂性指数增加的判断组合;
- 面向对象的流程,是分治,将易变的、脆弱的,拆分成多个稳定的对象,对象之间面向接口协作,复杂性拆分成局部复杂性,在大流程里是一个线性复杂性,在对象内是常数复杂性。
相比面向过程的流程的指数复杂性,这是数学上可证明的面向对象的优势。
软件工程设计的目标就是 kiss,一切围绕控制复杂性设计。
宏观面向对象,微观面向流程
上层的业务流程确实是面向过程的,但它又不负责具体的业务规则,而是编排。
- 宏观架构上,要"面向对象":划分好边界,把复杂的业务拆解成一个个职责明确、内聚的对象,以此来抗住需求的变更和系统的规模;
- 微观执行上,要"面向流程":在 Service 层,清晰、直观地把这些对象串联成一条条业务流,满足用户的实际需求。
对象是骨架,流程是血肉。
面向过程 vs 面向对象
面向过程
- 优点:逻辑简单直接,符合人类"按步骤做事"的直觉;代码体积小、执行效率高;调试和上手成本低,适合小型程序;
- 缺点:可维护性差,需求变更时需修改大量相关函数,牵一发动全身;复用性低;扩展性差,难以应对复杂系统的需求迭代。
面向对象
- 优点:可维护性强,封装使对象内部变化不影响外部,模块化降低耦合;复用性高,继承和多态大幅减少重复代码;扩展性好,新增功能只需定义新类/方法,无需修改原有代码(开闭原则);更贴合复杂问题的本质;
- 缺点:复杂度高,需设计类的结构、关系,上手门槛高;性能稍低;过度设计风险,简单问题可能被复杂化。
业务的悖论:用"空间对象"承载"时间流程"
“业务的本质是流程(时间推进),但为什么现代软件工程推崇对象(空间治理)?”
这是软件设计中最迷人的核心矛盾。
我们通过 DDD(领域驱动设计)思想完成了这两者的空间与时间平衡:
- 宏观架构上(空间划分)——面向对象:划分出干净、内聚的领域模型(如用户、商品、订单)。这些对象是系统的"零件",负责锁住状态与核心业务规则;
- 微观执行上(时间推进)——面向流程:在应用服务层,用直观的面向过程逻辑,将这些对象串联成一条条满足用户最终需求的"业务流"。
架构大智慧:对象是骨架(空间),流程是血肉(时间)。 好的代码,是用面向对象的画笔,画出面向过程的蓝图。
为什么业务是流,我们却要用对象?
为了应对"变化"和"规模"。
如果一个业务流程永远不改,面向过程绝对是最高效的。但现实是,业务流程会无限膨胀和变化。
- 面向过程的灾难:假设一个"下单流程",起初只有 3 步。随着业务发展,变成了 30 步,里面充斥着各种 if-else。最后这个流程长达几千行,没人敢改,因为改了第 5 步,可能会调断第 28 步的数据;
- 面向对象的解法:面向对象不是消灭流程,而是把流程中的"参与者(实体)“抽离出来,让它们自己负责自己的事情。下单流程不再是一条黑盒管道,而是变成了用户对象、商品对象、营销引擎对象、库存对象之间的交互。
用一个比喻来理解:
- 面向过程是"流水线工厂”:传送带上一条道走到黑,一旦产品要加个新功能,整条流水线可能都要停工重组;
- 面向对象是"现代企业组织":划分为财务部、销售部、研发部。公司的业务依然是一个个流程,但流程是由各个部门通过协作完成的。如果财务流程变了,只需要财务部内部调整,销售部根本不需要知道。
小结
- 流程是易变的、脆弱的,对象是稳定的、高内聚的;
- 面向对象的流程是分治,复杂性拆分成局部复杂性;
- 面向过程的流程是指数复杂性,面向对象是线性复杂性;
- 宏观架构上要面向对象,微观执行上要面向流程;
- 对象是骨架,流程是血肉;
- 用面向对象的画笔,画出面向过程的蓝图。