概述#
物件導向設計(OOD)題目要求應試者描繪出解決技術問題或現實物件的 class 架構與方法。這類題目考驗的是你能否設計出優雅、可維護的物件導向程式碼,而非你是否記得設計模式。表現不佳可能會被列為嚴重警訊。
How to Approach(解題步驟)#
無論是設計實體物件還是軟體系統,以下四個步驟適用於大多數 OOD 問題。
Step 1: Handle Ambiguity(釐清模糊性)#
OOD 題目通常是故意模糊的,用來測試你是否會主動問問題、還是直接假設並動手寫程式。一個不了解需求就寫程式的工程師,會浪費公司的時間和金錢,甚至造成更嚴重的問題。
面對 OOD 題目,應詢問:
- Who:誰會使用這個系統?
- How:他們如何使用它?
- 必要時可用「六個 W」框架:who, what, where, when, how, why
範例:設計一個咖啡機的物件導向結構。
- 是每小時服務數百位顧客、提供十種咖啡的工業用機器?
- 還是供老人使用的簡單家用機,只做黑咖啡?
- 使用情境不同,設計就完全不同。
Step 2: Define the Core Objects(定義核心物件)#
釐清需求後,思考系統中的「核心物件」是什麼。
範例:設計餐廳的 OOD。核心物件可能包括:
Table、Guest、Party、Order、Meal、Employee、Server、Host
Step 3: Analyze Relationships(分析關係)#
確定核心物件後,分析它們之間的關係:
- 哪些物件是哪些物件的成員(has-a)?
- 哪些物件繼承自哪些物件(is-a)?
- 關係是一對多還是多對多?
餐廳範例的關係設計:
Party應有一個Guest陣列Server和Host繼承自Employee- 每個
Table有一個Party,但每個Party可能有多個Table Restaurant有一個Host
要小心不要做錯誤假設。例如,一個
Table可能同時屬於多個Party(如時髦餐廳的共桌制)。應與面試官確認設計的通用程度。
Step 4: Investigate Actions(考察行為)#
此時已有基本架構,接下來思考物件之間的關鍵動作,以及這些動作如何影響設計。你可能會發現遺漏了某些物件,需要更新設計。
範例:
- 一個
Party走進Restaurant,Guest向Host要求一張Table Host查詢Reservation,若存在則分配Table給Party- 若不存在,
Party加入等候名單 - 當
Party離開,Table被釋放並分配給下一個Party
Design Patterns(設計模式)#
面試官評估的是你的能力,而非你對設計模式的記憶。設計模式的範疇遠超出面試所需。但 Singleton 和 Factory Method 這兩個模式在面試中較常見,因此在此介紹。
不要陷入「一定要找到某個設計模式來套用」的陷阱。設計應該解決眼前的問題。有時答案剛好符合某個模式,更多時候並不是。
Singleton Class(單例模式)#
Singleton 確保一個 class 只有唯一實例,並提供全域存取點。適合用於需要全域唯一物件的場景。
public class Restaurant {
private static Restaurant _instance = null;
protected Restaurant() { ... }
public static Restaurant getInstance() {
if (_instance == null) {
_instance = new Restaurant();
}
return _instance;
}
}許多人不喜歡 Singleton 模式,甚至稱其為「anti-pattern」。原因之一是它會干擾單元測試。
Factory Method(工廠方法模式)#
Factory Method 提供建立物件的介面,讓子類別決定要實例化哪個 class。可以讓 creator class 為抽象類別(不提供實作),或是提供一個接受參數決定實例化哪個 class 的具體方法。
public class CardGame {
public static CardGame createCardGame(GameType type) {
if (type == GameType.Poker) {
return new PokerGame();
} else if (type == GameType.BlackJack) {
return new BlackJackGame();
}
return null;
}
}本章面試題列表#
| 題號 | 題目 | 頁碼 |
|---|---|---|
| 7.1 | Deck of Cards(設計撲克牌資料結構) | pg 305 |
| 7.2 | Call Center(設計客服中心呼叫系統) | pg 307 |
| 7.3 | Jukebox(設計音樂點播機) | pg 310 |
| 7.4 | Parking Lot(設計停車場) | pg 312 |
| 7.5 | Online Book Reader(設計線上書籍閱讀系統) | pg 318 |
| 7.6 | Jigsaw(設計 NxN 拼圖) | pg 318 |
| 7.7 | Chat Server(設計聊天伺服器) | pg 326 |
| 7.8 | Othello(設計黑白棋遊戲) | pg 326 |
| 7.9 | Circular Array(實作可高效旋轉的環形陣列) | pg 329 |
| 7.10 | Minesweeper(設計踩地雷遊戲) | pg 332 |
| 7.11 | File System(設計記憶體內檔案系統) | pg 337 |
| 7.12 | Hash Table(設計使用 chaining 的 Hash Table) | pg 338 |