軟體開發通常從一個模糊的想法或特定的商業需求開始。為了將這些抽象的需求轉化為可運作的系統,工程師依賴結構化的方法論。物件導向分析與設計(OOAD)是此轉變過程中最穩健的框架之一。它將重點從程序式邏輯轉移到物件之間的互動,模擬現實世界中的實體及其行為。本指南提供了一條結構化的途徑,讓您在一天內從最初的構想轉化為具體的類圖。

理解核心哲學 🧠
在深入探討繪圖的機制之前,掌握物件導向思維背後的核心哲學至關重要。與程序式程式設計將程式碼圍繞動作和函數組織不同,物件導向設計則將程式碼圍繞資料以及操作這些資料的運作組織。在OOAD中,「物件」是基本的構建單元。
物件由兩個主要元件組成:
- 狀態: 描述物件在任何特定時刻的資料或屬性。
- 行為: 物件能夠執行的方法或運作。
當您使用OOAD分析一個系統時,實質上是在識別問題領域中的名詞(物件)與動詞(行為)。這種語言學的方法簡化了抽象的過程。您不再問「程式應該做什麼?」,而是問「涉及的物件有哪些,它們如何互動?」。
這種方法具有多項優勢:
- 模組化: 模組是自我封裝的,可獨立開發。
- 可重用性: 類別可以被繼承並在系統的不同部分重複使用。
- 可維護性: 只要介面保持穩定,一個物件的變更不一定會影響其他物件。
第一階段:概念化與需求 📋
第一天從收集資訊開始。若不了解問題,就無法設計解決方案。此階段著重於理解範圍與涉及的參與者。
識別參與者
參與者是指任何與系統互動的人或事物。參與者可以是人類使用者、外部系統或硬體裝置。列出參與者有助於界定系統的邊界。
- 主要參與者: 啟動互動以達成目標的使用者(例如:顧客、管理員)。
- 次要參與者: 支援主要參與者但非主要焦點的系統(例如:付款網關、電子郵件伺服器)。
定義使用案例
使用案例描述參與者與系統之間為達成某個結果而進行的特定互動。它回答的問題是:「參與者能做什麼?」。
- 範例: 「下訂單」是「顧客」的一個使用案例。
- 範例:「處理付款」是「付款服務」的一個使用案例。
在此階段,避免技術細節。專注於功能。記下你能想到的每一個獨特的互動。目前不必擔心系統如何實現這些功能;只需記錄這些功能必須發生即可。
第二階段:領域分析與建模 🏗️
一旦需求明確,重點便轉向領域。這包括識別商業環境中存在的概念。這一步驟彌補了商業需求與技術實現之間的差距。
提取名詞與動詞
檢視你的使用案例描述,並標示出名詞與動詞。這些是你的類圖的雛形。
- 名詞: 這些通常對應到類別。(例如:訂單、產品、客戶、發票)。
- 動詞: 這些通常對應到方法或關聯。(例如:建立、刪除、更新、傳送)。
區分實體
並非每個名詞都代表一個類別。有些名詞代表屬性。要區分類別與屬性,請問:「這個名詞是否具有獨立的身份與狀態?」
- 類別: 「客戶」具有姓名、地址與歷史記錄。它獨立存在。
- 屬性: 「姓名」是客戶的一個屬性。它本身並不存在。
第三階段:設計關係 🔗
物件並非孤立存在。它們彼此相關。定義這些關係對於功能設計至關重要。你必須理解四種主要的關係類型。
1. 關聯
關聯代表物件之間的結構性連結。它表示某一類的物件與另一類的物件相連。
- 範例: 一位客戶 擁有 一筆訂單。
- 方向: 可以是單向(客戶知道訂單)或雙向(訂單知道客戶)。
2. 聚合
聚合是一種特定的關聯類型,代表「整體-部分」關係。部分可以獨立於整體而存在。
- 範例: 一個部門 擁有 員工。如果部門解散,員工仍然存在。
- 符號: 通常在「整體」側以空心菱形表示。
3. 組成
組成是聚合的一種更強形式。零件無法在沒有整體的情況下存在。如果整體被摧毀,零件也會被摧毀。
- 範例: 一棟房子 擁有 房間。如果房子被拆除,房間就不復存在。
- 符號: 在「整體」側以實心菱形表示。
4. 繼承(泛化)
繼承允許一個類取得另一個類的屬性和行為。這促進了程式碼重用並建立層級結構。
- 範例: 「儲蓄帳戶」是一種「銀行帳戶」。
- 符號: 實線,並帶有指向父類的空心三角形。
階段 4:建立類圖 📐
類圖是您系統的藍圖。它可視化類別、屬性、方法和關係。這是您物件導向分析與設計(OOAD)流程的具體產出。
類別結構
圖中的每個類別通常分為三個部分:
- 名稱: 類別的識別符(例如,
顧客). - 屬性: 資料成員(例如,
顧客編號:整數,名稱:字串). - 方法: 行為(例如,
getBalance():浮點數,deposit(金額:浮點數)).
可見性修飾詞
使用可見性修飾詞來控制對類成員的存取。這對於封裝至關重要。
| 符號 | 修飾詞 | 可存取性 |
|---|---|---|
+ |
公開 | 可從任何地方存取。 |
- |
私有 | 僅可在類別內部存取。 |
# |
保護 | 可在類別及其子類別中存取。 |
~ |
套件 | 可在同一套件內存取。 |
基數與多重性
關係不僅僅是二元的;它們涉及數量。多重性定義了一個類別的實例與另一個類別的實例之間有多少個關聯。
- 1: 恰好一個。
- 0..1: 零個或一個。
- 1..*: 一個或多個。
- *: 零個或多個。
例如,一個顧客下訂單。一個1..*訂單由顧客下訂(在某些系統中,允許匿名訂單)。定義這些數量可防止系統設計中的邏輯錯誤。訂單由0..1顧客下訂(在某些系統中,允許匿名訂單)。定義這些數量可防止系統設計中的邏輯錯誤。
第五階段:細化與驗證 🛠️
繪製初始圖表後,根據需求審查圖表。圖表未經驗證前並未完成。此步驟確保設計符合預期功能。
驗證清單
- 完整性:所有使用案例是否都有對應的類別或方法?
- 一致性:相關類別之間的屬性類型是否一致?
- 清晰度:開發人員能否閱讀圖表並明確理解邏輯而無歧義?
- 可行性:系統是否能使用目前的技術堆疊實現?
常見的設計缺陷
在此階段應避免以下常見錯誤:
- 上帝類別: 包含過多邏輯與資料的類別。應將其拆分為較小且專注的類別。
- 細線式關係: 類別之間的關聯過多會導致緊密耦合。應追求鬆散耦合。
- 缺少屬性: 忘記需求中提到的關鍵資料欄位。
- 過度設計: 在必要之前就建立複雜的繼承層次結構。保持簡單。
深入探討:封裝與抽象 🛡️
在建立類別圖時,請牢記兩個原則:封裝與抽象。
封裝
封裝將資料與方法結合在一起,並限制對物件某些元件的直接存取。在您的類別圖中,這體現在將內部資料標記為私有,並公開方法以與其互動。
- 優點: 保護物件狀態的完整性。
- 實作: 在適當情況下使用設定器和取得器,但應公開代表業務邏輯的方法,而非僅簡單的資料存取。
抽象
抽象專注於隱藏複雜的實作細節,僅顯示物件的必要功能。這使得系統的不同部分能夠互動,而無需了解內部運作機制。
- 優點: 減少複雜度並提升模組化程度。
- 實作: 為需要特定行為的類別定義介面。確保類別圖反映出這些合約。
步驟式工作流程總結 🔄
為確保您能在一天內完成此流程,請遵循此時間順序的工作流程。
- 09:00 – 10:00: 收集需求並識別參與者。(用例清單)
- 10:00 – 12:00: 分析領域。識別名詞與動詞。(草擬類別)
- 12:00 – 13:00: 午餐休息與心智重置。
- 13:00 – 15:00: 定義關係與基數。(關聯映射)
- 15:00 – 17:00: 畫出類圖。加入屬性和方法。(最終圖)
- 17:00 – 18:00: 根據需求進行審查與驗證。(品質檢查)
長期成功的最佳實務 📈
雖然本指南涵蓋了快速入門,但維持高品質設計需要持續的紀律。在進入程式碼撰寫階段時,請遵循這些實務。
單一責任原則
確保每個類別只有一個變更的理由。如果一個類別同時處理資料儲存與商業邏輯,則過於複雜。應將關注點分離到不同的類別中。
介面隔離
客戶端不應被迫依賴它們不需要的介面。應設計小型、具體的介面,而非一個大型、封閉的介面。
依賴反轉
依賴抽象,而非具體實作。類圖應顯示高階模組依賴低階抽象(介面),而非特定的實作細節。
設計演進的結論 🌱
物件導向分析與設計並非一次性活動,而是一個迭代的過程。隨著需求的演進,你的類圖也必須隨之演進。今日結構良好的圖表,能降低明日變更的成本。透過聚焦於明確的名詞、穩健的關係與封裝的行為,你為可擴展的軟體奠定了基礎。
請記住,目標不是立即創造出完美的圖表,而是創造出清晰的溝通工具。這個工具能彌補商業利益相關者與技術開發人員之間的差距。當雙方都理解類圖時,開發就變成翻譯的過程,而非詮釋的過程。
你的圖表最終檢查清單 ✅
在簽核你的設計之前,請確認以下事項:
- 類別: 所有必要的類別都存在嗎?
- 屬性: 資料類型是否已定義且正確?
- 方法: 方法是否與需求中的動詞相符?
- 關係: 關聯、聚合與組合是否正確標示?
- 多重性: 基數(1, 0..1, *)是否正確?
- 可見性: 公共、私有與保護成員是否正確標示?
透過遵循此結構化方法,你將模糊的概念轉化為可執行的具體設計。物件導向設計是一項透過實踐磨練的技能,但從這些基礎步驟開始,能確保你朝專業軟體架構的方向穩步前進。












