開閉原則 (Open/Closed Principle, OCP):「軟件實體應對**擴展開放**,對**修改關閉**。」—— Bertrand Meyer。這是 SOLID 原則之首,也是所有設計模式的終極指向。本文透過稅率計算重構、Office/VS 插件架構剖析,揭示 OCP 的落地路徑與邊界。
電腦機箱的 USB 口:
軟件映射:抽象介面 = USB 協議;具體實現 = 設備驅動;宿主系統 = 作業系統。
識別**易變點** → 提取**抽象介面** → 依賴**抽象而非具體** → 提供**擴展點** (配置、DI、插件加載)。
static float GetTax(float salary) => salary * 0.03f; // 稅率寫死
// 稅法變更 → 必須修改此方法 → 違反 OCP
// 1. 抽象介面 (穩定契約)
public interface ITaxCalculator {
float Calculate(float salary);
}
// 2. 具體策略 (易變點封裝)
public class TaxBeforeConference : ITaxCalculator {
public float Calculate(float salary) => salary * 0.03f;
}
public class TaxAfterConference : ITaxCalculator {
public float Calculate(float salary) => salary * 0.02f;
}
// 3. 工廠/配置解析 (擴展點)
static ITaxCalculator CreateCalculator() {
string typeName = ConfigurationManager.AppSettings["TaxCalculatorType"];
return (ITaxCalculator)Activator.CreateInstance(Type.GetType(typeName));
}
// 4. 客戶端代碼 (永不修改)
static float GetTax(float salary) => CreateCalculator().Calculate(salary);
效果:稅法變更 → 新增 Tax2024Policy 類 → 修改配置文件 → **零代碼修改、零重編譯核心邏輯**。
| 系統 | 抽象層 | 擴展機制 |
|---|---|---|
| Office / VS | Add-in / VSPackage 介面 | COM/MEF 插件發現、清單文件、市場分發 |
| ASP.NET Core | Middleware / Service / Filter 介面 | DI 容器註冊、IApplicationBuilder.Use... |
| Entity Framework | IPlugin / IInterceptor | 模型構建約定、攔截器鏈 |
| 殺毒軟件 | 掃描引擎介面 | 特徵庫動態加載、引擎熱更新 |
| 三層架構 | DAL 介面 (IRepository) | 切換 SQL Server → MySQL 僅換實現類 |

「完全的 OCP 是不存在的,也不是目標。」 — Robert C. Martin
OCP 不是教條,而是**管理變化的藝術**。在「簡單設計」與「未雨綢繆」間找到平衡,是架構師的核心價值。