---
# System prepended metadata

title: 類與物件
tags: [' ']

---

# 類與物件

## 內容
- 類/物件/資料結構/容器
- OOP(SOLID, Law of Demeter)
- Polymorphism

## 物件(Object) vs 資料結構(Data Structure/Data Container)
- 物件：私有的內部屬性,使用公開的接口(類方法)去接觸
    - 抽象大於具體(不用知道內部細節)
    - 用途：
        - OOP style
        - 封裝
        - 分類業務邏輯
- 資料結構：公開的內部屬性(大部分公開),沒有接口(大部分)
    - 只有具體
    - 用途：
        - 儲存和傳遞資料

:::info
物件和資料結構兩者都可以使用類(Class)來實現
但內部運作原理和概念非常不同
:::

## 多態(Polymorphism)
讓物件擁有多種型態的能力
- 一個物件/方法
- 具有相同的結構/名稱
- 但會依據以下變化,呈現出不同功能
    - 如何創建
    - 如何使用
- 功能：
    - 減少代碼重複

## 乾淨的類
- 乾淨的類應該是輕巧的
- 很多小的類比一個大類更好
- 類應該有單一職責(Single-Responsibility Principle -> SRP)

### 如何判斷類是否過大
使用**內聚**(Conhesion)概念

### 內聚
類方法使用類屬性的程度

舉例(實際情況不會如此極端)
- 最大內聚
    - 所有的類方法都使用所有的類屬性
    - 使用：高度內聚的物件
- 無內聚
    - 所有類方法都沒有使用類屬性
    - 使用：
        - 資料結構
        - 帶有實用方法的容器

目標：實現高內聚

### 得墨忒耳法則--Law of Demeter (LoD)
又稱最少知識原則(principle of least knowledge)

延伸閱讀： [Law of Demeter](https://en.wikipedia.org/wiki/Law_of_Demeter)

內容：
- 不要越級訪問
- 不依賴其他對象的內部結構

實踐原則：
類方法中的代碼只會直接接觸其以下的內部事務(類屬性/其他類方法)：
- 方法所屬之物件
- 存儲在該物件屬性中的物件
- 當作參數傳入的物件
- 在方法中創建的物件

實踐方法：Tell, Don't Ask
- 不要向其他物件請求資訊,而是告訴他該做什麼
- 告訴代碼要做什麼,而不是跟代碼請求資訊後自己做

### SOLID Priciples(都跟可擴展/維護性有關,但只有第一/二個跟乾淨的代碼有關)
編寫 OOP 代碼時應該遵守的原則
- S：Single Responsibility Principle
    - 一個類處理一項職責
    - 透過限制類只能處理單一職責生成更輕巧的類
    - 輕巧的類更容易讀
- O：Open-Close Principle
    - 對於擴展(or 插件)開放
    - 對於修改封閉
    - 可以在不增長的情況下持續增加小類(維持可擴展性)
- L：Liskov Substitution Principle
    - 物件應該要可以被他的子類的實例替換,而不會改變其行為
    - 子類實例可以使用其父類的功能
    - 它確保您不會對資料用錯誤的方式建模
- I：Interface Segregation Principle
    - 介面分離原則
    - 眾多特定的介面比一個通用的介面好
- D：Dependency Inversion Principle
    - 依賴反轉原則
    - 應該要依賴抽象,而非實體
    - 顛倒依賴關係,把原本要在類中處理的事務,改為從外界傳入
    - 降低類的複雜程度
    - 易於維護
        - 可以使用依賴注入框架和方法在代碼中的幾個位置
        - 並在更多地方可以依賴於抽象的類




###### tags: Clean Code` `Note`