Composite パターン

Composite パターン - Wikipedia

容器(Composite)と中身(Leaf)を同一視(Component)して、再帰的な構造を作るデザインパターン。以下の例のようにファイルとフォルダの関係のようなもん。一般に木構造で書けるものはこのパターンが当てはまる。addメソッドをどこで実装するかには結構恣意性がある。

#include<list>
#include<iostream>
#include<string>
using namespace std;
//Component
class Component
{
public :
	Component(string name) : name_(name){};
	virtual ~Component(){};
	virtual void ShowStructure(string prefix) const = 0;
	string GetName() const{return this->name_;};
private :
	string name_;
};
//Leaf
class File : public Component
{
public : 
	File(string name) : Component(name){};
	~File(){}
	void ShowStructure(string prefix = "") const{
		cout << prefix << this->GetName() << endl;
	}
};
//Composite
class Folder : public Component {
public:
	Folder(string name) : Component(name){};
	~Folder(){
		list<Component*>::iterator it = children_.begin();
		while (it != children_.end()) {
			delete (*it);
			++it;
		}
	}
	void ShowStructure(string prefix = "") const{
		list<Component*>::const_iterator it = children_.begin(); 
		while (it != children_.end()) {
			(*it)->ShowStructure(prefix + this->GetName() + "/");
			++it;
		}
	}
	void Add(Component* c){
		children_.push_back(c);
	}
private:
	list<Component*> children_;    
};
//main
int main()
{
/*
C:\hoge.txt;
C:\huga.csv;
C:\temp\a.zip;
というフォルダ構造を作る
*/
	Folder* f1 = new Folder("C:");
	f1->Add(new File("hoge.txt"));
	f1->Add(new File("huga.csv"));
	Folder* f2 = new Folder("temp");
	f2->Add(new File("a.zip"));
	f1->Add(f2);
	//show
	f1->ShowStructure();
	delete f1;
	return 0;
}