中間的根據情境,將物件拆開,有幾種 pattern:
Service object • Query object • Form object • View object • Policy object
看到這我笑了... 喔,不,我哭了。這不是 Java 從一開始就在做的嗎?當初 Rails 就是嫌 Java 分太多層,太多 abstraction,才會生出只有 data model 和 controller 兩層,這樣簡化的 rails 架構。看來現在也得拆成不同大小的物件,分別職司不同的任務了。
系統大了,自然就會複雜,需要複雜的架構、抽象,不管你用什麼語言都一樣。Rails 已經能擔重任了,自然就要承受複雜帶來的問題。
anyway,回到原題。投影片說的沒錯,物件就是狀態和行為組成,要拆細物件,要朝行為著手,將多個行為合併後,就會有 role 的概念誕生,這裡講解的很好。
就我自身的經驗,我開始學 OOP 時,我只懂的看狀態。我看到 員工有工號,有職位,然後主管也有這些欄位,我就很開心的將主管去繼承員工來 重用
。我不曉得這只會在未來綁死自己而已 (繼承的階層是靜態不可變,無法應付需求改變)。
後來學乖了,就如同該文所說的,把 Doing 抽出來思考才對,不要用狀態去想。現在給自己定一些簡單的規則:
- 如果子類別沒有複寫父類別的行為,或是增加新的行為,那就不要用繼承。
- 盡量用 interface (指 Java),而且 interface 上的 method 都要是動詞,不是什麼 getter。
每當我實行上面的規矩時,我會發現設計出來的 class 的確有彈性的多,而且,就如投影片提的,最後都是 composition 為主,而不是繼承。不過這也是有代價的 -- 這需要時間。當我聞到臭味,發覺違反了上面的兩個基本規則時,便會開始進行重構。但直到滿足規則為止,都需要不斷的試誤,期間還得花心力去擠出別的做法,看看合不合適。
至於該不該投資這時間去完成這適當的 OOP 設計,就看需求而定了,如果是想做個高品質,重用性很高的函式庫,那這值得。如果只是每天的例行工事,那可能就算了。