【コンポジットパターン】

Compositeパターン とは?

最終更新:
💡 ひとつの要素も、要素のまとまりも同じ操作で

GoFの構造に関するデザインパターンの一つ。単一の要素と、子要素を持つまとまりを共通のインターフェースで扱い、部分と全体のツリーを表す。まとまりは必要に応じて子へ同じ操作を委ねる。

📌 このページのポイント
ひとつも、まとまりも同じ操作で共通の型 Component呼び出す側は getSize() を使うファイルとフォルダーで考える例フォルダー合計 300ファイルA値 100サブ合計 200ファイルB値 200Leafは自分の値Compositeは子へ処理を委ねる子を持つものも、入れ子にできる
getSize()を共通にした設計例です。緑のLeafは自分の値、橙のCompositeは子の値を合計します。灰色の線は子を含む関係で、型の継承や処理順の矢印ではありません。数字は例示で、OSの全ファイルAPIの仕様ではありません。
ひよこ ひよこ
Compositeパターンは、何を解決するの?
ペンギン先生 ペンギン先生
要素がひとつでも、複数をまとめたものでも、同じ操作で扱いたいときの設計だよ。例えば図形と図形のグループを、どちらも描画できるものとして扱う。呼び出す側で、種類ごとに処理を分ける負担を減らせるんだ
ひよこ ひよこ
ファイルとフォルダで、説明してもらえる?
ペンギン先生 ペンギン先生
ファイルは末端、フォルダは中身を持つまとまりという例だよ。両方にgetSize()を用意し、フォルダでは子のサイズを合算するように設計できる。これはパターンの説明例で、OSのすべてのファイルAPIが同じ動作をするという意味ではないんだ
ひよこ ひよこ
Component、Leaf、Compositeは、どうつながる?
ペンギン先生 ペンギン先生
Componentは共通の操作、Leafは末端の要素、Compositeは子を持つ要素だよ。子もComponentとして扱うので、Compositeの中に別のCompositeを入れられる。共通の操作があることと、すべて同じ処理をすることは別なんだ
ひよこ ひよこ
画面の部品にも使えるの?
ペンギン先生 ペンギン先生
部品を入れ子にし、同じように描画や操作をしたい場合に使えるよ。JavaのAWTでも、ContainerはComponentの一種で、他のComponentを含められる。どの操作を子へ委ねるかは実装するので、名前を付けるだけで再帰処理ができるわけではないんだ
ひよこ ひよこ
子を追加する操作も、Leafに必要?
ペンギン先生 ペンギン先生
共通の型に置く設計も、子を持つ型だけに置く設計もあるよ。前者は統一して呼びやすいけれど、Leafでは意味のない操作になる。後者は扱える型を限定できる。共通にしたい操作と、子の管理に必要な操作を分けて検討するんだ
ペンギン
まとめ:ざっくりこれだけ覚えればOK!
「Compositeパターン」って出てきたら「ひとつの要素と要素のまとまりを、同じ操作で扱うツリーの設計」と思えばだいたいOK!
📖 おまけ:英語の意味
「Composite Pattern」 = 合成・複合のパターン
💬 compositeは複数のものを組み合わせた、という意味だよ。GoFのDesign Patterns(1994年刊行)で整理された構造パターンの一つで、部分と全体を組み合わせる設計を指すんだ

参考資料

← 用語集にもどる