OCP 由 Bertrand Meyer 於 1988 年提出,是軟體工程中最著名的原則之一。
它的核心定義看似矛盾,實則深奧:
OCP 定義:
「軟體實體(類別、模組、函數等)應對擴展開放,但對修改封閉。」
(A software artifact should be open for extension but closed for modification.)
這意味著:當需求改變時,我們應該透過增加新的程式碼來擴展系統行為,而不是去修改既有的程式碼。
一、架構層次的 OCP#
許多人認為 OCP 只是「使用介面(Interface)和繼承」的類別設計原則。
但在架構層次,OCP 扮演更宏觀的角色:劃分元件並管理依賴關係。
Uncle Bob 使用一個「財務報表生成器」的例子來說明。
假設系統原是生成網頁版(Web)報表,現在需要增加列印版(Print)報表。
- 理想情況: 只需增加新的「列印展示層(Print Presenter)」程式碼,
而完全不需修改核心「財務計算邏輯(Interactor)」

Figure 8.1: Applying the SRP
二、依賴的方向:保護高層元件#
為了達到 OCP,我們須將系統劃分為不同元件(Components),
並透過介面控制原始碼依賴方向(Dependency Direction)。
1. 層級劃分 (Level of Components)#
- 高層級(High-level): 核心業務規則(如 Interactor)。它們是系統存在的理由,最不應改變
- 低層級(Low-level): 周邊實作細節(如 Database, Web Controller, Presenter)。
它們是為支援業務規則而存在,經常變動

Figure 8.2: Partitioning into classes and components
2. 保護機制 (Protection Hierarchy)#
架構設計的目標是:讓高層級免受低層級元件變更的影響。
- 規則: 依賴關係(➡️)須永遠指向更高層級的方向
Web Controller➡️ 依賴 ➡️InteractorDatabase➡️ 依賴 ➡️InteractorPresenter➡️ 依賴 ➡️Interactor
- 結果: 當
Database或Web介面改變時,核心Interactor完全不需修改(對修改封閉)。
反之,如果要增加新展示方式,我們只需擴展新的Presenter(對擴展開放)。

Figure 8.3: Component relationships are unidirectional
三、結論#
OCP 是系統架構的指南針:
- 劃分元件: 將系統拆解為負責不同職責的元件
- 依賴倒置: 確保低層級細節依賴於高層級策略
- 單向保護: 讓核心邏輯成為系統最穩定、不需被修改的部分
如果你的架構設計得當,面對需求變更時,
你應會輕鬆(只需寫新 class),而不是恐懼(害怕改壞舊 code)。