設計軟體架構的過程在撰寫任何程式碼之前就已開始。它從理解資料與行為在系統內如何互動開始。類別圖即是此結構的藍圖,用以呈現系統的靜態結構,顯示類別、屬性、操作與關係。本指南將帶你快速從零開始建立穩固的類別圖。
無論你是開發人員、業務分析師還是系統架構師,清晰度都至關重要。將物件導向設計可視化,有助於團隊早期發現潛在問題。它能確保所有人對系統行為達成共識。遵循結構化的方法,可避免常見的設計過度複雜化陷阱。我們將專注於核心元素、邏輯流程,以及連結系統的各項關係。

理解核心元件 🧱
在繪製線條之前,你必須先理解基本構件。類別圖由特定元素組成,每個元素在統一模型語言(UML)標準中都有其特定含義。跳過這項基礎,往往會導致後續令人困惑的模糊圖表。
- 類別: 基本單位。代表具有相似特徵與行為的物件類別。
- 屬性: 類別中所持有的資料。這些是定義狀態的屬性。
- 操作: 可用來與資料互動的方法或函數。
- 可見性: 表示存取權限。常見符號包括 + 表示公開,– 表示私有,# 表示保護。
定義類別時,一致性至關重要。類別使用名詞,操作使用動詞。屬性應描述狀態。例如,如果你有一個 客戶 類別,屬性可能包括 姓名 或 電子郵件。操作可能包括 註冊 或 登入.
可見性與修飾符
存取權限的控制對於封裝至關重要。你必須決定內部狀態暴露的程度。以下是標準可見性符號的快速參考:
| 符號 | 名稱 | 存取層級 |
|---|---|---|
| + | 公開 | 可從任何地方存取 |
| – | 私有 | 僅可在類別內存取 |
| # | 受保護 | 可在類別及子類別中存取 |
| ~ | 套件 | 可在相同套件內存取 |
正確使用這些符號可避免在實作階段產生混淆。這向其他開發人員傳達了程式碼中哪些部分是穩定的,哪些是內部實作細節。
15分鐘工作流程 ⏱️
在建模時,時間管理至關重要。過長的設計會議可能導致效益遞減。目標是在不陷入細節的同時,捕捉關鍵結構。將時間分為三個明確階段,以確保能高效地從概念轉向結構。
第一階段:腦力激盪與識別(0-5分鐘) 🧠
從問題領域開始。目前還不要考慮程式碼。思考涉及的現實世界實體。閱讀需求或功能規格。找出名詞。這些名詞很可能會成為你的類別。
- 閱讀使用者故事或使用案例。
- 列出所有提及的重要實體。
- 過濾掉像這樣的通用詞彙
管理員或系統除非它們具有特定的責任。 - 將相關實體歸類在一起。
例如,在電商情境中,你可能會識別出產品, 訂單, 顧客,以及付款。這些是你的候選項目。把它們記下來。你將在下一階段驗證它們的必要性。
第二階段:定義結構與屬性(5-10分鐘) 📝
現在,詳細列出類別。針對每個候選項目,定義必要的屬性。問問自己:「這個實體包含哪些資訊?」保持清單專注於當前範圍所需的內容。避免加入未來可能需要的功能的屬性。
- 客戶:
識別碼,姓名,地址,電子郵件. - 產品:
SKU,價格,描述,庫存. - 訂單:
訂單識別碼,日期,總金額.
接下來,定義操作。問:「這個實體可以執行哪些動作?」或「它會觸發哪些動作?」
- 客戶:
placeOrder(),updateProfile(). - 訂單:
calculateTotal(),cancel().
套用可見性修飾符。預設將屬性設為私有。公開屬於介面的公共操作。這種紀律能讓設計保持乾淨且模組化。
第三階段:建立關係(10-15分鐘) 🔗
最後一個階段是連接類別。關係定義了物件之間如何互動。這是圖表中最重要的部分。錯誤的關係會導致緊密耦合和維護上的噩夢。請審查您實體之間的互動。
- 一筆
客戶是否有多個訂單? - 一筆
訂單是否包含產品? - 一筆
付款是否依賴於一筆訂單是有效的嗎?
在類別之間繪製線條。清楚標示。使用適當的關係類型。不要猜測。如果不确定,請參考下方詳細的關係指南。
深入探討關係 🧩
關係定義了模型的語義。它們講述了資料如何流動以及物件之間如何相互依賴的故事。你需要掌握五種主要類型。理解它們之間的差異對於準確的表示至關重要。
1. 關聯
關聯代表兩個類別之間的結構性關係。它表示一個類別的物件與另一個類別的物件相連結。這是最通用的關係類型。
- 範例:一
駕駛員駕駛一輛汽車. - 方向:可以是單向或雙向的。
- 標籤:通常以角色名稱標示(例如「駕駛」)。
關聯線是實線。如果關係是雙向的,兩端都不需要箭頭。如果是單向的,則在導航至另一個類別的類別一端加上箭頭。
2. 聚合
聚合是關聯的一種特殊形式。它代表一種「擁有」關係,其中部分可以獨立於整體存在。通常被描述為一種弱關係。
- 範例:一
部門擁有員工. - 邏輯:如果你刪除
部門,該員工仍然存在。 - 視覺呈現: 整體側面有一個空心菱形。
這種關係對於建模集合很有用。它表示容器管理集合的生命周期,但不管理其中的單個項目。
3. 組合
組合是一種強形式的聚合。它代表一種「部分對整體」的關係,其中部分無法在沒有整體的情況下存在。其生命週期是相互依賴的。
- 範例: 一
房屋有房間. - 邏輯: 如果你刪除
房屋,那麼房間將被銷毀。 - 視覺: 整體側面有一個實心菱形。
當子物件僅屬於父物件時,使用組合。這在資料結構中很常見,物件會隨著容器的建立與銷毀而一同建立與銷毀。這強制執行所有權的嚴格界限。
4. 繼承(泛化)
繼承允許一個類別取得另一個類別的屬性和行為。它促進程式碼重用並建立層次結構。子類別是超類別的特殊化版本。
- 範例:
車輛是超類別。汽車和腳踏車都是子類別。 - 邏輯: 一
汽車是一種車輛. - 視覺: 一條實線,搭配一個空心三角形箭頭,指向超類別。
請小心不要建立過深的層次結構。保持層次結構淺顯,以維持可讀性。如果一個類別繼承太多,將變得脆弱且難以維護。
5. 依賴
依賴是一種使用關係。它表示一個類別的變更可能會影響另一個類別。這種關係通常是暫時性或暫時存在的。
- 範例: 一個
報表產生器使用一個資料庫連接. - 邏輯: 如果
資料庫連接發生變更,那麼報表產生器可能會失效。 - 視覺: 一條虛線,搭配一個開放的箭頭。
依賴是所有關係中最脆弱的一種。它暗示了一種暫時性的關聯。通常透過方法參數或區域變數來解決。應盡量減少依賴,以降低耦合度。
基數與多重性
關係很少是一對一的。你必須明確指出有多少個實例參與此關係。這稱為基數或多重性。它能釐清系統的規則。
- 1: 嚴格來說只有一個實例。
- 0..1: 零個或一個實例。
- 1..*: 一個或多個實例。
- 0..*: 零個或多個實例。
套用這些約束可防止邏輯錯誤。例如,指出一個客戶 有 0..1 地址 表示他們可能沒有。指出一個訂單 有 1..* 項目 表示訂單不能為空。
建立清晰模型的最佳實務 🌟
結構良好的圖表是自解釋的。它只需要最少的註解就能被理解。遵循既定的慣例可使合作更輕鬆。遵循這些指南以維持高品質。
保持簡單
不要包含所有存在的屬性。專注於與目前情境相關的資料。如果一個圖表有五十個類別,很可能太複雜了。將其分解為子系統或套件。使用模組化來隱藏不必要的細節。
一致的命名慣例
命名是一種溝通工具。使用清晰且具描述性的名稱。除非是業界標準,否則避免使用縮寫。類別應為名詞。操作應為動詞。屬性應描述狀態。
- 不良:
cust,getInfo,val. - 良好:
客戶,fetchData,值.
尊重迪米特定律
物件只能與其直接朋友對話。避免呼叫其他方法所傳回物件的方法。這能降低耦合度。如果你發現自己在物件圖中深入導航,應重新考慮你的設計。這可能表示類別之間耦合過於緊密。
檢查循環
檢查循環依賴。如果類別 A 依賴類別 B,而類別 B 又依賴類別 A,你可能有設計問題。這通常會導致程式碼中的初始化錯誤。透過引入介面或中介者來打破循環。
應避免的常見錯誤 🚫
即使經驗豐富的設計師也會犯錯。了解常見陷阱能幫助你避免犯錯。在最終確定模型前,請根據此清單審查你的工作。
- 混雜職責: 一個類別應專精於一件事。如果一個類別同時處理資料庫存取與使用者介面邏輯,應將其拆分。
- 忽略介面: 過度依賴具體類別會使測試變得困難。盡可能使用介面來定義合約。
- 過度使用繼承: 優先使用組合而非繼承。繼承會造成緊密耦合。組合則提供更高的彈性。
- 遺漏多重性: 未標示關係線會使意義模糊不清。務必明確標示基數。
- 靜態與實例: 不要混淆靜態成員與實例成員。靜態成員屬於類別本身,而非特定實例。在符號表示中應清楚呈現此區別。
設計的最後想法 🚀
建立類別圖是一種抽象練習。你正在將複雜的需求轉譯為簡化的視覺表示。目標不是完美,而是清晰。能幫助理解的圖表就是成功的。
請記住,圖表是活文件。隨著需求變更,模型也必須演進。將其視為引導開發過程的地圖。在程式碼審查時重新檢視,以確保實作符合設計。
透過遵循結構化的方法,你可以在短時間內產出高品質的模型。專注於核心實體,定義明確的關係,並使用標準符號。此基礎能支援可擴展且易維護的軟體架構。保持設計簡單、命名清晰、關係邏輯明確。









