概要
Composite(コンポジット)パターンは、
オブジェクトの「個」と「集合(コンテナ)」を同じインターフェースで扱う設計パターンである。
再帰的な構造(ツリー・ディレクトリ構造・UI構成など)において、操作の一貫性を保ちつつ柔軟に構成を拡張可能にする。
1. なぜCompositeが必要か?
❌ 個別ノードと複合ノードで扱い方が異なるとコードが複雑に
if isinstance(node, Leaf):
node.draw()
else:
for child in node.children:
child.draw()
→ 条件分岐による処理の分散・冗長化
✅ 全てを draw()
に統一して再帰的に呼び出す構造へ
root.draw()
→ クライアントコードが構造を意識せず操作可能
2. 基本構造
✅ Componentインターフェース
class Graphic:
def draw(self):
raise NotImplementedError
✅ Leaf(葉ノード)
class Circle(Graphic):
def draw(self):
print("● Circle")
✅ Composite(枝ノード)
class GraphicGroup(Graphic):
def __init__(self):
self.children = []
def add(self, graphic: Graphic):
self.children.append(graphic)
def draw(self):
print("[Group] Start")
for child in self.children:
child.draw()
print("[Group] End")
✅ 使用例
root = GraphicGroup()
circle1 = Circle()
circle2 = Circle()
subgroup = GraphicGroup()
subgroup.add(circle2)
root.add(circle1)
root.add(subgroup)
root.draw()
出力:
[Group] Start
● Circle
[Group] Start
● Circle
[Group] End
[Group] End
3. Python的応用:ファイルツリー風Composite構造
class FileSystemNode:
def show(self, indent=0):
raise NotImplementedError
class File(FileSystemNode):
def __init__(self, name):
self.name = name
def show(self, indent=0):
print(" " * indent + f"- {self.name}")
class Folder(FileSystemNode):
def __init__(self, name):
self.name = name
self.children = []
def add(self, node: FileSystemNode):
self.children.append(node)
def show(self, indent=0):
print(" " * indent + f"[{self.name}]")
for child in self.children:
child.show(indent + 1)
root = Folder("project")
root.add(File("README.md"))
src = Folder("src")
src.add(File("main.py"))
root.add(src)
root.show()
出力:
[project]
- README.md
[src]
- main.py
4. 実務ユースケース
✅ UI構築(ページ内コンポーネントの入れ子構造)
→ Panel
, Button
, TextBox
などを一貫した操作で管理可能
✅ ファイルシステム・階層型メニューの表現
→ ルートから末端まで統一操作
✅ DOM操作・シーングラフ・パーティクル構造
→ 構造と描画の分離を再帰で美しく表現
✅ ワークフローや処理フローの構造設計
→ タスク
と サブタスク集合
を同一視できる構成
5. よくある誤用と対策
❌ CompositeにLeafの操作を持たせてしまう
→ ✅ 共通インターフェースは最小限にし、不要な操作を排除
❌ 子ノードの操作を外から乱用する(カプセル化の破壊)
→ ✅ add()
/remove()
はCompositeの責務、Leafでは持たせない
❌ 構造の再帰処理が深くなりすぎてパフォーマンス劣化
→ ✅ 最大深度・遅延描画・メモ化等の最適化を検討
結語
Compositeパターンとは、“構造の深さを抽象の一貫性で隠し、操作を平坦にする設計”である。
- 個と集合を同じように扱うことで、再帰構造の一貫性と汎用性を獲得
- 入れ子構造やツリー構造の操作を、再帰と抽象で美しく設計
- Pythonでは柔軟なインターフェース設計と再帰構文で、極めて直感的に実装可能
Pythonicとは、“階層に意味を持たせながら、それを意識させないように操作すること”。
Compositeパターンはその均質性と抽象力を、再帰の奥に潜ませる技法である。