Einar Landre
封裝的層次#
在**系統理論(systems theory)**中,**封裝(containment)**是處理大型複雜系統結構最有用的構造之一。在軟體產業中,封裝的價值被廣泛認可,並由程式語言中的各種構造支持:副程式、函式、模組、套件、類別等。
- 模組和套件處理較大規模的封裝需求
- 類別、副程式和函式處理較細粒度的部分
然而,多年來作者發現類別是開發者最難正確使用的封裝構造。常見的錯誤包括:一個類別有一個 3,000 行的 main 方法,或者一個類別只有 set 和 get 方法來存取原始屬性。
物件封裝行為與狀態#
物件同時封裝狀態(state)和行為(behavior),其中行為由實際狀態定義。考慮一個門(door)物件,它有四種狀態:closed、open、closing、opening,並提供兩種操作:open 和 close。
這種將行為與狀態綁定的特性讓設計過程概念上非常簡單,歸結為兩個任務:
- 職責分配(allocation of responsibility)
- 職責委派(delegation of responsibility),包括物件間的互動協議
實際範例:訂單系統#
假設有三個類別:Customer、Order 和 Item:
Customer是信用額度和信用驗證規則的天然持有者Order知道其關聯的Customer,其addItem操作透過呼叫customer.validateCredit(item.price())來委派實際的信用檢查- 如果後置條件失敗,就拋出例外並中止購買
反面模式:打破封裝#
經驗較少的物件導向開發者可能會將所有商業規則塞進一個物件,通常稱為 OrderManager 或 OrderService。在這種設計中,Order、Customer 和 Item 被當作不過是記錄型別(record types)。所有邏輯從各類別中抽出,塞進一個大型的程序式方法中,充滿 if-then-else 結構。
這些方法極易出錯且幾乎不可能維護。原因就是封裝被破壞了。
不要打破封裝——善用你的程式語言的力量來維護它。讓每個物件擁有自己的行為,而不僅僅是資料。