Composite Pattern
讓使用者將物件合成為樹狀結構,呈現「部分/整體」的階層關係。如此可讓使用的程式以相同的方式處理單獨或合成的物件。這句話沒解釋的話根本看不懂吧……
讓樹狀結構的 node 都是同樣的 interface,因而可以用相同的方式(相同的 interface)操作 subtree root node(合成物件)以及操作 leaf node(單獨物件)。
UML
Composite
就是 tree 中非 leaf 的 node。Client
可以透過 Component
interface 同時操作 leaf node 及 subtree node。
這做法會讓 Leaf
繼承一些它不需要的 function 如 getChild()
。實作上可以在 Component
class 將 function 們的 default 行為 implement 成「不 support 此操作」,由 Composite
跟 Leaf
override 對其有意義的 function。至於「不 support 此操作」的實作方式可以是丟出 exception、印 log、return false 等等……
設計取捨
Component
interface 包含對 leaf node 沒意義、對 subtree root node 才有意義的操作,就這個 interface 來看包含了兩種責任,操作 leaf node 與操作 subtree root node,不符合 class 單一責任的設計原則。不過呢,這就是設計上的取捨,以單一責任交換能統一操作 tree 中的 node,實際使用上就是要看情境決定哪一個比較重要。
似曾相識的 fu (?)
範例程式生一堆 Component 又 add 來 add 去,看著看著總覺得跟 Qt 的 QStandardItem 寫法很像。看了下 Qt 的 code,QStandardItem
不像是用 composite pattern,應該是打從一開始就定義 item 是個可以有 child 的東西了。
這也是為什麼上一篇是用 QStandardItem 當例子…