軟體危機:硬體飛躍與軟體滯後的鋸齒差
1960s-70s,摩爾定律驅動硬體指數級增長,但軟體開發仍停留在「手工作坊」階段:
- 進度失控、預算超支、品質低落
- 交付系統「用之不靈、棄之可惜」甚至無法交付
- 1968 年 NATO 軟體工程會議正式命名為「軟體危機」
結構化程式設計:第一次工程化嘗試
1970s 流行的面向過程 (Procedural) 方法論:
- 自頂向下功能分解
- 模組化、結構化 (序列/選擇/迴圈)
- 適用場景:演算法導向、數學計算、編譯器、科學計算
核心缺陷:資料與函數分離——全域資料被多函數存取,耦合度高,修改一處牽一髮動全身。
面向過程在複雜系統中的崩潰
| 問題 | 說明 |
| 資料與行為分離 | 不符合人類認知真實世界的方式 (實體 = 狀態 + 行為) |
| 修改擴散 | 資料結構變更 → 所有存取函數需同步修改 |
| 重用困難 | 函數依賴特定資料結構,難以抽離 |
| 維護噩夢 | 自頂向下設計產生剛性階層,新需求需重構整棵樹 |
物件導向誕生:封裝、繼承、多型三大支柱
1967 Simula 67 首創類別/物件/繼承;1970s Smalltalk 確立純 OOP;1980s C++、Objective-C 推向主流;1990s Java、C# 普及企業級開發。
OOP 核心優勢
- 封裝:資料與操作綁定,隱藏內部實作,透過介面互動
- 繼承:類別層級復用,「是一種」關係建模
- 多型:介面統一、實作多樣,支援開放封閉原則
- 抽象:忽略細節、聚焦本質,管理複雜度
範式對照:同一問題的兩種建模
// 面向過程:資料結構 + 操作函數
struct Employee { int Id; string Name; double Salary; }
void CalculateBonus(Employee* e, double rate);
void PrintPayroll(Employee* list, int count);
// 面向物件:實體封裝
class Employee {
public int Id { get; }
public string Name { get; }
public double Salary { get; private set; }
public double CalculateBonus(double rate) => Salary * rate;
public void PrintPayroll() { ... }
}
何時選擇 OOP?何時選擇其他範式?
| 問題領域 | 建議範式 | 理由 |
| 科學計算、演算法密集、資料流轉換 | 面向過程 / 函數式 | 無狀態、可組合、易平行化 |
| 企業業務系統、領域模型豐富、長期演進 | 面向物件 (DDD) | 封裝業務規則、模擬真實世界 |
| 規則引擎、專家系統、邏輯推理 | 面向邏輯 / 規則 | 宣告式規則、推理機分離 |
| 高併發、事件驅動、資料流管線 | 函數式 / 反應式 | 不可變狀態、無副作用 |
總結
OOP 並非銀彈,而是針對「複雜、長期演進、領域知識密集」系統的工程化回應。理解其誕生脈絡——從軟體危機、結構化程式設計的局限、到封裝/繼承/多型的抽象機制——有助於在架構決策中理性選擇範式,而非盲目追隨潮流。
- 上一篇文章: 面向物件核心四概念:物件、類別、繼承、通訊與 C# 實現機制
- 下一篇文章: C# 流程控制完整指南:選擇、迴圈、跳轉、條件編譯與例外處理
Copyright ©
程式碼之家 All Rights Reserved