Chain of Responsibility パターン

Chain of Responsibility パターン - Wikipedia

複数のオブジェクトを鎖のようにつないでおき、そのオブジェクトの鎖を渡り歩いて目的の処理ができるまでたらいまわしにする。ここではNoSupport→LimitSupport→OddSupportクラスのオブジェクトの順に渡り歩き処理ができるまでたらいまわしにされるようになってる。

#include <iostream>
#include <string>
using namespace std;
//data object
class Trouble
{
public :
	Trouble(int number) : number_(number){}
	int GetNumber() const{return this->number_;}
private :
	int number_;
};
//Handler
class Support
{
public :
	Support(string name) : name_(name), next_(NULL){}
	virtual ~Support(){
		if(next_ != NULL){
			delete next_;
		}
	}
	string GetName() const{return name_;}
	Support * SetNext(Support * next){
		this->next_ = next;
		return next;
	}
	void Request(const Trouble & trouble){
		if(Resolve(trouble)){
			cout << "Problem " << trouble.GetNumber() << " is solved by [" << this->GetName() << "]" <<endl;;			
		}
		else if(next_ != NULL){
			next_->Request(trouble);
		}
		else{
			cout << "Problem " <<trouble.GetNumber() << " can't be solved" << endl;;
		}
	}
private :
	virtual bool Resolve(const Trouble & trouble) = 0;
	Support *next_;
	string name_;
};
//Concrete Handler 1
class NoSupport : public Support
{
public :
	NoSupport(string name) : Support(name){}
private:
	bool Resolve(const Trouble & trouble){return false;}
};
//Concrete Handler 2
class LimitSupport : public Support
{
public :
	LimitSupport(string name, int number) : Support(name), number_(number){}
private:
	bool Resolve(const Trouble & trouble){
		return(trouble.GetNumber() < this->number_ ? true:false);
	}
	int number_;
};
//Concrete Handler 3
class OddSupport : public Support
{
public :
	OddSupport(string name) : Support(name){}
private:
	bool Resolve(const Trouble & trouble){
		return(trouble.GetNumber() % 2 == 1? true : false);
	}
};

//main 
Support * CreateSupporter()
{
	Support *alice  = new NoSupport("Alice");
	Support *bob    = new LimitSupport("bob",10);
	Support *Damian = new OddSupport("Damian");
	alice->SetNext(bob)->SetNext(Damian);
	return alice;
}
int main()
{
	Support *supporter = CreateSupporter();
	for(int i = 0;i < 20; i++){
		supporter->Request(Trouble(i));
	}
	delete supporter;
	return 0;
}