🕐 ~8 分鐘閱讀
📝 關於這篇文章的筆記
這篇文章基於我個人對物件導向程式設計(OOP)和SOLID原則的學習筆記。為了讓這些筆記更易讀、更有用——不僅僅是對我自己,也對其他人——我與人工智能合作,幫助擴展和整理它們,使其成為一個完整的部落格格式。這些想法、學習旅程和認知是我自己的;人工智能幫助了寫作和表達。
好的程式碼並非偶然產生。每個令人愉悦的程式碼庫背後,都有一套引導事物結構和連接方式的觀念。
本文涵蓋了這段完整旅程——從物件導向程式設計是什麼,物件如何相關,壞設計的樣子,以及最終:綁定所有內容的五個 SOLID 原則。
我們開始吧。
第一部分:物件導向程式設計是什麼?
面向物件編程 (OOP) 是一種寫代碼的方式,它反映了現實世界。它不是一長串的指令,而是將相關的數據和行為組合成 物件。
🤖 考慮一個機器人玩具。它有 屬性 (顏色、高度、電池) 和 行為 (走路, 說話, 挥手). 在物件導向程式設計中,那個機器人是物件 — 而用來建立它的藍圖稱為一個 class.
兩個關鍵術語:
- Class — 藍圖 (範本)
- Object — 從藍圖建立的一個實例
四大支柱
| 柱 | 它的功能 |
|---|---|
| 繼承 | 子類別繼承自父類別的屬性和行為 |
| 封裝 | 內部資料隱藏 — 只允許受控的訪問 |
| 抽象化 | 複雜的內部結構隱藏;僅暴露所需的內容 |
| 多形性 | 同一個動作可能因對象不同而表現出不同的行為 |
第二部分:物體如何互關聯
物體並非孤立存在。它們互相連接、合作,並依賴於彼此——而關係的類型至關重要
關聯
兩個物體互相了解,可以互動。有三種基本關係範疇:
- 一對一 — 每人一簽證
- 一對多 — 一位老師,多名學生
- 多對多 — 多名學生,多門課程
在關聯中,當一個對象「擁有」另一個對象時,關係是:
- 聚合 (鬆散) — 兒童無需父母也能存活。書包裡有書本,但即使你丟掉書包,書本依然存在。
- 組成 (緊密) — 兒童無法離開父母而存活。房子有房間;拆毀房子,房間便不再存在。
依賴關係
一種暫時性、基於使用的關係。一個類別在方法內使用另一個類別,但並不永續持有它。比關聯弱
擴充 & 執行
- 擴充 — 從多個類別中提取共用特徵到一個超類別(繼承)
- 執行 — 一個實現介面的類別,承諾履行一個已定義的合約
第三部分:壞設計的樣子
在學習規則之前,了解你要防禦的對象有助於學習。Robert C. Martin 指出了壞設計的三個症狀:
🪨 僵固 — 系統難以改變。觸及一點,其他許多事物就需要更新。開發者變得擔心進行改變。
🍪 脆弱 — 當你進行改變時,系統會在預期之外的場所崩潰。你修復了支付模組的錯誤,不知何故郵件通知停止工作。
🏗️ 僵固 — 有用的組件不能被重用。它們與其周圍的環境緊密耦合,提取它們的時間會比從頭開始重寫還要長。
三者都有相同的根本原因:組件之間依賴關係的管理不佳。
第四部分:SOLID
SOLID 是一套五個原則,直接解決上述問題。每個原則針對一種特定的失敗模式.
S — 單一責任原則
"一個模組應該僅對一個,而且僅對一個,參與者負責。"
每一個類別應該有確切地一個改變的理由 — 它服務一個參與者(一組利害關係人)。
👨🍳 一位同時擔任廚師、收銀員、保安和外賣司機的餐廳工人是個即將發生的災難。一個角色的變化就會打亂所有其他角色。
將你的職責分開。每個職責只負責一項。
O — 開閉原則
「軟體產品應該對擴展開放,但對修改封閉。」
通過擴展 — 不是透過編輯現有的、可運作的程式碼.
🔌 一個排插讓你能夠在不重繞排插本身的情況下插入新的設備。這就是OCP(開放封閉原則)的實踐.
當需求改變時,將新的程式碼與舊的並置 — 不要重寫已經運作良好的部分.
L — Liskov替換原則
"若 S 是 T 的子類型,則類型為 T 的物件可以被類型為 S 的物件取代,而不改變程式正確性。"
子類別必須 完全可取代 其父類別。父類別所做的每一個承諾,子類別必須遵守。
🤖 若父機器人能烹飪,子機器人也必須能烹飪 — 不拋出錯誤或默默不做任何事。
若你的子類別有空的 方法、偽實現 或拋出 "不支援" 的拋出 — 那是 Liskov 违規.
我 — 接口分割原則
「客戶端不應被迫依賴他們不使用的接口。」
不要創建過胖的接口,迫使類別實現他們不需要的方法。 分割接口 切割成更小、更專注的單元.
🍴 當客戶只點了湯時,不要給他們每一個餐廳客戶牛排刀、湯匙、筷子,還有fondue釘。
更小的介面 = 更狹窄的依賴 = 變更保持在地.
D — 依賴反轉原則
"高階模組不應依賴低階模組。兩者都應依賴抽象概念。"
您的商業邏輯不應該硬編程到特定的實現中。它應該與介面 — 而低層細節實現這些介面.
🤖 不要把餅乾刮刀焊接到機器人的手臂上。給手臂一個標準連接器,並讓工具可以隨意更換。
這就是為什麼基礎設施(資料庫、API、檔案系統)可以無需觸及商業邏輯即可替換.
快速參考:SOLID 一覽
| 原則 | 它解決的問題 | 需要問的關鍵問題 |
|---|---|---|
| 單一職責原則 | 做太多事的類別 | 「這個類別是否服務超過一組利益相關者?」 |
| OCP | 修改舊程式碼以增加功能 | "我可以把它作為擴充套件而不是修改嗎?" |
| LSP | 損壞的繼承階層 | "我可以把子類換成父類而不會有任何問題嗎?" |
| ISP | 過胖的介面帶有未使用的 方法 | "這個類別是否被迫實作它不需要的功能?" |
| DIP | 商業邏輯鎖定在基礎設施 | "我的高階程式碼是否依賴於它不應該依賴的具體類別?" |
從何開始
如果你是第一次使用這些原則:
- 從單一職責原則開始 — 找出你「做得太多」的課程並將它們拆分
- 檢查LSP違規 — 空方法就是警示信號
- 在基礎設施邊界引入介面 — 這就是實踐中的DIP
這些原則不是清單。它們是你每次坐下寫代碼時要問的問題。
原發表於sanudin.dev











