一次搞懂物件導向程式設計的特性

三大特性、五大原則、以及其他名詞解釋

會寫程式很簡單,寫出好的程式很難。上次寫了一篇 Clean Code 筆記,算是比較進階的,最近剛好複習了比較基本的一些物件導向相關原則與特性,於是就寫出了這篇。

這些物件導向的基本觀念和 Clean Code 一樣,平常可以幫助自己讓 code 寫得更易懂且更好維護,而且 Code Review 時可以拿來嗆同事(X),同時也算是面試的熱門考題之一,因此一次整理成一篇記下來,希望能幫助到自己和其他剛好找到這篇的人。

這邊主要以條列和簡單說明為主,因為我相信原則和定律皆由其簡單的解釋方式,若要更深的討論也是可以分別寫成文章的,但就不是這篇的目的了。

如果你認為有寫錯或需要補充的,也歡迎留言或寄信告訴我。

Software Implementation Goal

  • Robustness 可以處理預料外的 input
  • Adaptability 在不同平台與環境之間的變動越小越好(現在可以透過 docker 實現)
  • Reusability 重複使用

Design Pattern 的面向

Algorithms: Recursion / Divide-and-conquer / Amortization …

Software Design: Template method / Composition / Adapter / Decorator …

Software Architecture: MVC / Event Sourcing …

物件導向程式設計(Object-Oriented Programming,OOP)

三個 Design Principle

  • Abstraction 抽象化
    • 將一個複雜的系統,用簡單的方式精準呈現,而不需要知道其實作細節
      • ADT abstract data type: 描述資料結構
    • 可藉由定義 Public interface 來實現
    • Interface vs Class: Interface 是抽象的(what),Class 是細節的(how)
      • A class implements an interface
  • Encapsulation 封裝
    • 一個元件的內部狀態要可以被隱藏
    • Public / Protected / Private
      • Protected 的子類別可以存取,而 Private 不行
  • Modularity 模組化
    • 軟體的不同元件要被分散於不同 functional unit

Hierarchical Organization

→ reusability

  • Inheritance 繼承
    • Specialization: 於子類別 override 其 methods
    • Extension: 於子類別新增 methods
  • Polymorphism 多型
    • 一個變數可以是多種型別
    • 同名 function 能根據其 Input 型別 去 call 不同 function → Overloading
    • 同名 method 能根據其 Class 去 call 實際上於不同 class 的 method → Duck Typing
    • 類似 functional programming 的 pattern matching

網路上常看到的三大特性:封裝、繼承、多型

SOLID Principle

目的:減少「改程式」。

Single Responsibility Principle / SRP 單一職責原則

一個 function 應該只有一個讓你去修改他的理由(一種職責)

Open Closed Principle / OCP 開放閉合原則

要設計得易於延展(例如:繼承、增加新 function),不用因新型態、新需求加入而改變原本的部分

Liskov Substitution Principle / LSP 里氏替換原則

子類別要能夠完全支援父類別的功能

Interface Segregation Principles / ISP 介面隔離原則

介面功能單一化,不要有龐大的介面

Dependency Inversion Principle / DIP 依賴反轉原則

Dependency Injection 依賴注入:讓實作類別 (class) 依賴抽象類別 (interface),不要讓兩個實作類別直接依賴

參考資料