加载中...

本篇要回答的问题:架构的本质是业务的正交分解,那么如何应对需求的变化?著名的开闭原则(OCP)背后真正的架构哲学是什么,它为什么不只是 OOP 的编程技巧?

上一讲谈全局性功能,点出架构分解的两大难题——需求的交织需求的易变。本讲正面回答后者:怎么应对变化。许式伟把架构设计的工具收敛为两个:组合(用小业务拼大业务)与应对变化(开闭原则)。本讲就是把 OCP 从一句口号还原成"架构治理的根本哲学"。

开闭原则(OCP)是什么

OCP 由 Bertrand Meyer 在 1988 年《面向对象软件构造》中首次提出:

软件实体(模块/类/函数)应对功能扩展开放,对修改封闭。

维度 说明
核心主张 通过扩展行为应对变化,而非修改现有代码
背后哲学 推崇模块业务的确定性:可改 Bug,但不轻易调整业务范畴
与正交分解的关系 一脉相承——与其改业务,不如实现一个新业务模块
"只读"思想 模块一经设计就不改;要变就废弃它,转而实现新模块

关键判断:OCP 鼓励写"只读"的业务模块。这种只读思想和 Git 源码版本管理、容器服务治理同源——都靠"只读"来降低系统治理难度,让可复用模块越积越多。

CPU 背后的架构思维:OCP 不止于 OOP

把 OCP 误解成 OOP 编程思想太狭隘。它是信息技术架构的基本原则。冯·诺依曼体系的 CPU 设计就是 OCP 的完美体现:

稳定点(封闭) 变化点(开放) 带来的能力
指令集稳定 指令序列多变 → 发明了软件 解决一切可计算问题
计算稳定 数据交换多变 → 定义 I/O 规范 适应不断革新的交互技术
CPU 不变 缺页中断把外存/文件系统格式解耦给操作系统 中断 = CPU 引入的回调函数

洞见:我们从不修改 CPU,却支撑了多姿多彩的信息世界。这与面向对象无关,完全是开闭原则的威力。

插件机制:让代码不变而业务能变

OCP 关注的是模块而非最终软件。对"软件"这个大模块若坚持业务不变就是放弃进步。让代码不变、业务范畴却能适应变化,靠的就是插件机制(DOM API 二次开发、生态型软件如 Office / Visual Studio)。

完整插件机制的三个部分:

组成 作用 难度
软件能力暴露(DOM API) 插件调用已实现的功能 最基础
插件加载机制 基于文件系统目录或 Windows 注册表 中等
事件监听 没有事件,插件无法介入业务 关键且最难

事件设计追求少而精,一般分三类:

事件类别 典型例子 说明
界面操作类 菜单/按钮点击 鼠标键盘太底层,是双刃剑,一般不直接暴露
数据变更类 onSelectionChangedonDataChanged 对应 MVC 中 Model 层发出的变更通知
业务流程类 Office 打开文件前/后 发生在业务流中间或完成后

关键判断:插件机制可大可小。Go 的 image 包(import _ "image/jpeg")放弃了自动加载机制、改为手工加载,就是轻量插件的范本。但插件机制本身也是核心系统的功能,没有足够通用性、没几个客户的插件机制就是投入产出失衡

OCP 与单一职责原则(SRP):一体两面

原则 强调点
开闭原则(OCP) 把模块业务的变化点抽离出去,交给别的模块
单一职责原则(SRP) 每个模块只负责一个业务,不同时干多个

二者谈的本质是同一个问题的两个面。

总结

OCP 总结为两点:① 模块业务要稳定,遵循"只读"设计,要变就归档放弃;② 变化点简单的用回调/接口开放,复杂的引入插件机制,分解为"最小化核心系统 + 多个正交周边系统"。回调/接口本质是事件监听,是插件机制的特例。架构师除业务架构外,还要慎重选择基础架构——基础架构 + 业务架构才是软件的全部。

先把"是什么"回答清楚

概念 一句话说明
开闭原则(OCP) 对扩展开放、对修改封闭,鼓励写"只读"业务模块
"只读"设计 模块一经设计不再改,要变就废弃重写新模块
插件机制 让核心代码不变而业务能扩展的手段:能力暴露+加载+事件
单一职责(SRP) 一个模块只干一个业务,与 OCP 是一体两面

一句话速记

把稳定的核心压到最小最封闭,把会变的部分用回调/接口/插件开放出去——OCP 不是 OOP 技巧,而是从 CPU 到 Git 到容器都在用的架构治理根本哲学。

几条值得记住的判断

  • OCP 关注模块,不是最终软件;软件这个大模块必须靠插件机制进步。
  • 事件越少越好,但要少而精,这极度依赖架构能力。
  • 维持通用性是提供插件机制的前提,否则投入产出失衡。

思考题

回到你自己的项目:有没有某个模块,你总是在反复"修改"它来满足新需求?它该被抽出一个事件/插件点对扩展开放,还是干脆按"只读"思想归档、重写一个新模块?

公告栏
这是我的个人知识库。
记录技术,也记录生活 —— 读过的、试过的、想明白的,都堆在这儿。
最新文章
网站资讯
文章数目 :
5
已运行时间 :
本站总字数 :
15.7k
本站访客数 :
本站总访问量 :
最后更新时间 :
全局知识图谱
当前页面 已访问 文章 标签
ESC 关闭 · 滚轮缩放 · 拖拽移动 · Ctrl+G 开关