以多型取代條件式 (Replace Conditional with Polymorphism)

★★★★★Draft

FromRefactoring

📚 From the Books

以多型取代條件式 (Replace Conditional with Polymorphism)Refactoring Moves

複雜的條件邏輯很難理解。一種改善法是把它拆解到不同的環境裡——用類別與多型,能讓這種分解更明確:每個子類別實作自己那一支邏輯,取代原本的 if/switch 判斷。

🧠 Why It's a Problem

同一個 switch/if-else 依「型別」分岔、又散落在多處時,每加一個新型別就得回去改每一個判斷。用多型後,型別各自成類,行為關進自己的子類別,新增型別只要多寫一個類別。

TIP

判斷訊號:if/switch 的每個分支對應「一種東西」而非「一種情況」。前者適合多型;後者(特例、前置檢查)適合 Replace Nested Conditional with Guard Clauses

⚖️ Refactoring

機械步驟:① 建立一個基底類別,讓每個型別成為它的子類別 → ② 把含條件式的方法搬到基底 → ③ 取條件式的一個分支,在對應子類別覆寫該方法、放入該支邏輯 → ④ 對每個分支重複 → ⑤ 基底方法留預設或設為抽象,移除原條件式 → ⑥ 測試。

前 — 用 vehicle_type 一路 if/elif
class Vehicle {
  constructor(vehicleType) {
    this.vehicleType = vehicleType;
  }

  getSpeed() {
    if (this.vehicleType === 'car') {
      return 100;
    } else if (this.vehicleType === 'bicycle') {
      return 20;
    } else if (this.vehicleType === 'boat') {
      return 30;
    } else {
      return 0;
    }
  }
}

每多一種載具,就得回到這個 switch 加一支;相同的型別判斷散到哪個方法都要再寫一次。

後 — 每個子類別實作自己的邏輯
class Vehicle {
  getSpeed() {
    return 0;
  }
}

class Car extends Vehicle {
  getSpeed() {
    return 100;
  }
}

class Bicycle extends Vehicle {
  getSpeed() {
    return 20;
  }
}

class Boat extends Vehicle {
  getSpeed() {
    return 30;
  }
}

const car = new Car();
console.log(`Car speed: ${car.getSpeed()}`);

條件式消失,型別判斷交給多型分派。新增一種載具=多寫一個子類別,不必碰既有程式碼。

NOTE

這個手法讓程式碼貼近幾個經典設計模式:把「一族可替換的行為」抽成子類別,正是 Strategy 的形狀;若行為隨物件狀態切換,則接近 State。它也體現了對擴充開放、對修改封閉的精神。

🔑 Takeaways

✍️ My Notes

No notes yet — jot your takeaways or Q&A here.

📖 Further Reading

🔗 Dive Deeper