GoFデザインパターン23個を完全に理解するブログ #08 Composite(コンポジット)

2025/11/03

プログラミング

t f B! P L
eyecatch 「構造パターン」の代表格、Composite(コンポジット)パターンについて解説します。 ツリー構造(階層構造)を扱う設計で、とてもよく使われるパターンです。 目的は、「個(オブジェクト)」と「集合(グループ)」を同じように扱えるようにすること。 イメージとしては、フォルダとファイルを、どちらも「開く」「削除する」といった同じ操作で扱えます。 「木構造(ツリー)」を再帰的に構築できるようにするためのデザインパターンですね。

よくある例

・OSのファイルシステム(フォルダとファイル) ・HTMLのDOMツリー(親要素と子要素) ・組織図(部門と社員)
分野 Compositeの実例
Web DOMツリー(ElementとNodeList)
GUI メニュー構造、ボタンやパネルの入れ子
ファイル操作 OSのフォルダ・ファイル管理
組織管理 部署(Composite)と社員(Leaf)

サンプルコード

「ファイルとフォルダを同じ操作で扱う」ケースのソースコードです。

Component(共通インターフェース)

class FileSystemItem { show(indent = 0) { throw new Error("show()を実装してください"); } }

Leaf(葉:実体のあるファイル)

class File extends FileSystemItem { constructor(name) { super(); this.name = name; } show(indent = 0) { console.log(" ".repeat(indent) + "📄 " + this.name); } }

Composite(枝:フォルダ)

class Folder extends FileSystemItem { constructor(name) { super(); this.name = name; this.children = []; } add(item) { this.children.push(item); } show(indent = 0) { console.log(" ".repeat(indent) + "📁 " + this.name); for (const child of this.children) { child.show(indent + 2); } } }

実行例

const root = new Folder("root"); const src = new Folder("src"); const img = new Folder("images"); src.add(new File("index.js")); src.add(new File("app.js")); img.add(new File("logo.png")); root.add(src); root.add(img); root.add(new File("README.md")); root.show();

出力結果

📁 root ├ 📁 src │├ 📄 index.js │└ 📄 app.js ├ 📁 images │└ 📄 logo.png └ 📄 README.md

解説ポイント

File と Folder はどちらも 同じ型(FileSystemItem) を継承する。 同じ型にすることで、名称やアイコン保持などの属性を共通化することができます。 違いは、子階層の配列を持っているかどうか(または、fileとfolderなどのtypeを付与しておく)。 実際に使用する呼び出し側は、「ファイルかフォルダか」意識せずに操作できる。 属性判定のクラス(または関数)を作っておくだけで、判別も構造化できます。 再帰的に呼び出して、階層構造を簡潔に表現できる。 同列内のファイルやフォルダの検索などが便利に行えるのは、構造を理解するとわかりやすいですね。

メリット

・階層構造をシンプルに扱える(再帰処理が簡単)。 ・「個」と「集合」を同一視でき、呼び出し側のロジックが統一される。 ・新しい要素(ファイルタイプなど)を追加しやすい。

デメリット

・構造がやや抽象的になりすぎると理解しづらい。 ・再帰処理の中でパフォーマンスが落ちる可能性(大量データ時)。 ・ループ検出などを考慮しないと無限再帰になるリスク。

あとがき

ブランチ階層構造的に、親となるオブジェクトの内部に、子要素を配列で格納していき、ツリー構造モデルを構築するやり方です。 もっと他にもシンプルな書き方もできるかもしれませんが、オブジェクトデータで保持することで、拡張性などが高くなるので、GUI系で使えるパターンですね。 MVCパターンのモデル部分でこのデザインパターンを使うことで、運用効率がアップするイメージが持てました。

人気の投稿

このブログを検索

ごあいさつ

このWebサイトは、独自思考で我が道を行くユゲタの少し尖った思考のTechブログです。 毎日興味がどんどん切り替わるので、テーマはマルチになっています。 もしかしたらアイデアに困っている人の助けになるかもしれません。

ブログ アーカイブ