本章將 Chapter 28 所學的元件設計原則實際應用於薪資系統,逐步分析並重組元件結構,最終得出一個符合 ADP、SDP、SAP 等原則的元件配置。
元件結構與內聚性分析#

Figure 30.1: Possible payroll component diagram
- 第一步是根據 CCP(共同封閉原則)將類別分組:因相同原因而變化的類別放在同一個元件中
- 初步的分組方式是根據功能領域:
- PayrollDomain:核心領域物件(Employee、PaymentClassification 等)
- PayrollDatabase:資料庫存取
- TransactionImplementation:交易實作
- TransactionApplication:應用程式入口
- TextParser:文字指令解析器
套用耦合性原則#

Figure 30.3: Updated payroll component diagram
- 檢查 ADP(無環依賴原則):確認依賴圖中不存在循環
- 發現
TransactionImplementation與PayrollDomain之間可能存在問題——Transaction 類別直接存取了TimeCard等領域物件的建構子

Figure 30.4: Revision to TimeCardTransaction to protect TimeCard privacy
- 為了保護
TimeCard的封裝性,修改TimeCardTransaction使其透過HourlyClassification的方法來新增時間卡,而非直接操作TimeCard物件 - 這遵循了 REP(再利用/發布等價原則):讓
PayrollDomain可以獨立於 Transaction 實作被重用
指標計算與分析#

Figure 30.6: Component diagram with metrics
- 針對每個元件計算 Ca、Ce、I、A、D’ 指標
- 分析結果:
PayrollDomain:高穩定性(低 I),高抽象度(高 A)——位於主序列附近,是理想的核心元件TransactionApplication:穩定但具體——需要增加抽象度,或重新評估其依賴關係TextParser:高不穩定度(高 I),低抽象度(低 A)——也位於主序列附近,適合作為外層元件
補充: 指標是輔助工具而非目標。作者強調不應為了讓數字好看而做不必要的重構,而是在發現異常指標時深入調查是否存在真正的設計問題。
使用 Factory 模式解耦#

Figure 30.8: Static structure of main program and object factories

Figure 30.9: Dynamic structure of main program and object factories
- 為了讓
TransactionImplementation不直接依賴PayrollDatabase的具體實作,引入 PayrollDatabaseFactory 介面 main程式負責建立所有 Factory 的具體實作,並注入到系統中- 這確保了依賴方向始終朝向穩定與抽象
最終元件結構#

Figure 30.10: Final payroll component structure
- 最終的元件配置滿足了所有六大原則:
- ADP:無循環依賴
- SDP:依賴方向朝向穩定
- SAP:穩定的元件是抽象的
- CCP:因相同原因變化的類別在同一元件中
- CRP:不一起使用的類別不在同一元件中
- REP:每個元件可獨立發布與重用
重點: 元件結構不是一次設計好的。它隨著系統的演化而改變——在開發早期,你可能只有一兩個元件;隨著類別增加、依賴變複雜,才逐步分割與重組。元件設計原則提供的是持續檢視與改進的框架。
本章小結#
本章展示了如何將抽象的設計原則轉化為具體的架構決策。透過指標計算,我們可以量化地評估設計品質;透過 Factory 模式,我們可以打破不必要的依賴;透過反覆迭代,我們可以漸進地改善元件結構。