Composite パターン - コンポジットパターン
2008/06/13 21:29Update
Composite パターンはGoFによる23種類のデザインパターンの構造に関連するパターンです。Composite パターンでは、「ツリーのような再帰的なデータ構造」を同一インタフェースで扱えることができます。
はじめに
ツリーのような「枝」と「葉」を持つデータ構造は少なくがありません。次は、再帰的な構造であるファイルシステムの例です。
C:\
|
+---Windows
| |
| + AppPatch
| |
| + AcLayers.dll
| + Config
| |
| + somefile1.txt
| + somefile2.txt
+---MyWorks
| |
| + Folder001
| |
| + AcLayers.dll
| + Folder002
| |
| + somefile1.txt
| + somefile2.txt
...
フォルダの中にファイル(葉)を存在したり、サブフォルダ(枝)を存在したり、さらにサブフォルダの中にもファイルやフォルダを存在したり・・・
Composite パターンは、このようなデータ構造を同一インタフェースで処理することによって、容易に扱えるようになります。
Composite パターンを使えば、「枝」であろうか、「葉」であろうか、関係なく同じインタフェースで取り扱いを行うことができます。
Composite パターンの使用シーン
◇ 再帰的なデータ構造の取り扱いが必要
◇ 取り扱いをより簡単な方法で行いたい
Composite パターンのクラス図
<<クラス図>>
Component:再帰的なデータ構造の抽象。次のような機能を提供する。
- 本来のインタフェースの定義
- 子データセットの管理(追加、削除、アクセス)
- 親データへのリンク(オプション)
Leaf:「葉」クラス。Componentから継承。
Composite:「枝」クラス。Componentから継承。
Composite パターンの使用例
Composite パターンは実装は次の通りです。
1、Component抽象クラスを定義します
2、Leaf(葉)クラスを定義します
3、Composite(枝)クラスを定義します
先ほど述べたファイルシステムの例をComposite パターンで実装してみたいと思います。
※以下はJava言語による実装です。ほかの言語も同じような考え方です。
import java.util.ArrayList;
import java.util.List;
//Component抽象クラスに相当する IFile.java
interface IFile {
public void printName();
//子供追加
public boolean addChild(IFile file);
//子供削除
public boolean removeChild(IFile file);
//子供取得
public List<IFile> getChildren();
}
//Leaf(葉)クラスに相当する File.java
class File implements IFile {
private String name;
public File(String name) {
this.name = name;
}
public void printName() {
System.out.println(name);
}
//子供はないので、空実装
public boolean addChild(IFile file) {
return false;
}
//子供はないので、空実装
public boolean removeChild(IFile file) {
return false;
}
//子供はないので、空実装
public List<IFile> getChildren() {
return null;
}
}
//Composite(枝)クラスに相当する Folder
class Folder implements IFile {
private String name;
private List <IFile> childList;
public Folder(String name) {
this.name = name;
this.childList = new ArrayList<IFile>();
}
public void printName() {
System.out.println(name);
}
//子供追加
public boolean addChild(IFile file) {
return childList.add(file);
}
//子供削除
public boolean removeChild(IFile file) {
return childList.remove(file);
}
//子供取得
public List<IFile> getChildren() {
return childList;
}
}
そして、使い方は
import java.util.ArrayList;
import java.util.List;
public class Client {
public static void main(String[] args) {
//再帰的なデータ構造を構築
Folder rootFolder = new Folder("c:\\");
Folder compositeFolder = new Folder("composite");
rootFolder.addChild(compositeFolder);
Folder windowsFolder = new Folder("windows");
rootFolder.addChild(windowsFolder);
File file = new File("TestComposite.java");
compositeFolder.addChild(file);
//再帰的なデータ構造をアクセス
printTree(rootFolder);
}
private static void printTree(IFile ifile) {
ifile.printName();
List <IFile> children = ifile.getChildren();
for (IFile file:children) {
if (file instanceof File) {
System.out.print(" ");
file.printName();
} else if (file instanceof Folder) {
printTree(file); //再帰
}
}
}
}
実行結果は以下になります。
C:\Composite>javac *.java
C:\Composite>java Client
c:\
composite
TestComposite.java
windows
C:\Composite>
C:\Composite>java Client
c:\
composite
TestComposite.java
windows
C:\Composite>
Sponsored Link
- Relative Articles
- ASP.NETでのフロント・コントローラ(Front Controller)実装 - (2009/10/20 15:22)
- Factory Method パターン - ファクトリメソッドパターン - (2008/06/09 22:44)
- Abstract Factory パターン - 抽象ファクトリパターン - (2008/06/10 13:25)
- Singleton パターン - シングルトンパターン - (2008/06/10 15:36)
- Prototypeパターン - プロトタイプパターン - (2008/06/10 17:23)
- Builderパターン - ビルダーパターン - (2008/06/10 19:01)
- Adapter パターン - アダプターパターン - (2008/06/11 11:30)
- Interpreter パターン - インタプリタパターン - (2008/06/13 15:42)
- Chain of Responsibility パターン - 責任の連鎖パターン - (2008/06/14 00:28)
- Mediator パターン - 仲介者パターン - (2008/06/15 01:40)