Composite パターン

Composite パターン（コンポジット・パターン）とは、GoF (Gang of Four; 4人のギャングたち) によって定義された
デザインパターンの1つである。「構造に関するパターン」に属する。Composite パターンを用いるとディレクトリとファイルなどのような、木構造を伴う再帰的なデータ構造を表すことができる。
Composite パターンにおいて登場するオブジェクトは、「枝」と「葉」であり、これらは共通のインターフェースを実装している。そのため、枝と葉を同様に扱えるというメリットがある。
クラス図.
Composite パターンのクラス図を以下に挙げる。
利用例.
Composite パターンを用いてディレクトリ構造を表すJavaプログラムの例を示す。
このプログラムは、
から構成される。
 import java.util.ArrayList;
 import java.util.List;
 interface FileInterface {
 public void defaultMethod(int depth);
 public List<FileInterface> getChildren();
 public boolean addComponent(FileInterface c);
 public boolean removeComponent(FileInterface c);
 
 class File implements FileInterface {
 private String name;
 public File(String name) {
 this.name = name;
 
 public void defaultMethod(int depth) {
 for (int i = 0; i < depth; i++) System.out.print(" ");
 System.out.println("file:" + this.name);
 
 
 class Folder implements FileInterface {
 private String name;
 private List<FileInterface> fileList = new ArrayList<FileInterface>();
 public void defaultMethod(int depth) {
 for (int i = 0; i < depth; i++)
 System.out.print(" ");
 System.out.println("folder:" + name);
 for (FileInterface file : fileList) {
 file.defaultMethod(depth + 1);
 
 public class DirectoryUser {
 public static void main(String [] args){
 FileInterface root = new Folder("root");
 FileInterface usr = new Folder("usr");
 FileInterface var = new Folder("var");
 FileInterface home = new Folder("home");
 FileInterface user1 = new Folder("user1");
 FileInterface file1 = new File("file1");
 root.addComponent(usr);
 usr.addComponent(var);
 root.addComponent(home); 
 home.addComponent(user1);
 user1.addComponent(file1);
 root.defaultMethod(0);
実行結果
folder:root
 folder:usr
 folder:var
 folder:home
 folder:user1
 file:file1
注意事項.
Composite パターンを用いる際には、データ構造がきちんと木構造を保つようにしなければならない。
親子関係が循環してしまった場合、codice_1を実行した際に無限ループに陥るからである。
例えば、利用例のソースコードを書き換えた以下のプログラムは、処理が
codice_2
の行に達した時に、無限に出力し続けてしまう。
 public class LoopExample {
 public static void main(String [] args){
 FileInterface dir1 = new Folder("dir1");
 FileInterface dir2 = new Folder("dir2");
 FileInterface dir3 = new Folder("dir3");
 dir1.addComponent(dir2);
 dir2.addComponent(dir3);
 dir3.addComponent(dir1); 
 dir1.defaultMethod(0);