知识卡片

OCP在架构层面的核心机制:不想被修改影响的组件应被依赖

结构图卡

内容

开闭原则(Bertrand Meyer,1988年)要求设计良好的软件应该易于扩展、同时抗拒修改——对原始需求的小小延伸如果需要大幅修改原有系统,就说明架构设计失败了。用一个财务数据展示系统(既要在网页上滚动显示、又要生成分页报表)的思想实验来说明如何落地:先按[[SRP的真正含义是只对一类行为者负责而非只做一件事]]把”计算报表数据”和”生成具体展示(网页/纸质)”拆成两个独立操作,再调整这些拆分出来的组件之间的依赖关系(依赖反转),确保修改一个操作不会波及另一个操作。整个系统被划分成Controller、Interactor、Database、Presenter+View这些组件,所有组件间的依赖关系被设计成单向的,箭头统一指向”不想被经常修改”的组件——这浓缩成一条核心设计原则:如果A组件不想被B组件上发生的修改所影响,就应该让B依赖于A。这套关系天然形成了保护层级:Interactor(包含最高层次的应用策略,即核心业务逻辑)处在被保护得最严密的位置,Database/Controller/Presenter/View上发生的任何修改都不会波及它;Controller虽是Interactor的附属品,却是Presenter和View所服务的核心,层级依次降低。软件架构师的工作,正是根据相关函数被修改的原因、方式、时间对其分组隔离,再把这些隔离的分组整理成组件结构,让高阶组件不因低阶组件的修改而受影响。

结构图

flowchart TD
    View1[View 网页展示] --> Presenter1[Presenter 网页]
    View2[View 报表展示] --> Presenter2[Presenter 报表]
    Presenter1 --> Controller
    Presenter2 --> Controller
    Controller --> Interactor[Interactor: 核心业务逻辑,受保护程度最高]
    Database --> Interactor
    Interactor -.高层策略,不因下游修改而受影响.-> Interactor

参考来源

- 位置:《架构整洁之道》第8章《OCP:开闭原则》"思想实验"(源文件:_epub-src/text/part0012_split_002.html) - 结论依据:原文用财务数据展示系统的思想实验说明如何用SRP拆分操作、用依赖反转控制方向,并明确给出"如果A组件不想被B组件的修改所影响,就应该让B依赖于A"的核心原则,说明Interactor因是核心业务逻辑所在而被保护得最严密,直接支撑本卡片的结构图与解释。 - 原始内容:如果A组件不想被B组件上发生的修改所影响,那么就应该让B组件依赖于A组件……Interactor组件是整个系统中最符合OCP的……因为它是该程序的业务逻辑所在之处,Interactor中包含了其最高层次的应用策略。