この場合、子オブジェクトがリーフの場合とノードの場合で伝達方法が異なる点に注意していただきたい。 伝達対象の違いによる分岐がアルゴリズムに生じる分、操作アルゴリズムが複雑になることが予想されるわけである。 一方、Compositeパターンはリーフとノードを区別せずに全ての子オブジェクトを操作することができるため、 より軽量な操作アルゴリズムをクライアントに提供することができる。 ポイントはリーフとノードに同じクラスを継承させているという点である。 このように異なるクラスを同じクラスとして扱い、両者の区別をさせない(できない)状態を "Erich Gamma - Design Patterns"ではTransparencyと呼んでおり、デザインパターンではしばしば重要な概念とされている。
Transparencyを前面に扱っているものとしてDecoratorパターンが挙げられる。 Decoratorパターンでは装飾されるクラスと装飾を行うクラスを区別させないような巧妙な手口が用いられており、 クライアントにシンプルなインターフェイスを提供している。
//main.as package { import flash.display.Sprite; import composite.ANode; import composite.Node; import composite.Leaf; public class main extends Sprite{ public function main(){ var root:ANode = new Node("root"); var node0:ANode = new Node("node0"); var node1:ANode = new Node("node1"); var leaf0:ANode = new Leaf("leaf0"); var leaf1:ANode = new Leaf("leaf1"); var leaf2:ANode = new Leaf("leaf2"); var leaf3:ANode = new Leaf("leaf3"); var leaf4:ANode = new Leaf("leaf4"); root.addChild(node0); root.addChild(node1); node0.addChild(leaf0); node0.addChild(leaf1); node1.addChild(leaf2); node1.addChild(leaf3); node1.addChild(leaf4); root.notify("hello"); } } }
//main.as output root: hello node0: hello leaf0: hello leaf1: hello node1: hello leaf2: hello leaf3: hello leaf4: hello
//ANode (Abstract) package composite{ import flash.errors.IllegalOperationError; public class ANode{ protected var _name:String; public function get name():String{ return _name; } /** * Constructor */ public function ANode(name:String){ _name = name; } public function addChild(c:ANode):void{ throw new IllegalOperationError("addChild not supported: " + Object(this).constructor); } public function notify(message:String):void{ throw new IllegalOperationError("notify not supported: " + Object(this).constructor); } } }
//Node.as package composite{ public class Node extends ANode{ protected var _children:Array; /** * Constructor */ public function Node(name:String){ super(name); _children = new Array(); } override public function addChild(c:ANode):void{ _children.push(c); } override public function notify(message:String):void{ trace(_name + ": " + message); for each (var c:ANode in _children){ c.notify(message); } } } }
//Leaf.as package composite{ public class Leaf extends ANode{ /** * Constructor */ public function Leaf(name:String){ super(name); } override public function notify(message:String):void{ trace(_name + ": " + message); } } }