책임 연쇠( chain of Responsibility )

Posted 2012. 10. 23. 17:42

메시지를 보내는 객체와 이를 받아 처리하는 객체들 간의 결합도를 없애기 위한 패턴.

하나의 요청에 대한 처리가 반드시 한 객체에서만 이루어지지 않고, 여러 객체에게 그 처리의 기회를

주려는 것이다. 즉, 이 패턴에서는 하나의 서비스 처리를 여러 객체에 나눌 수 있도록 한다.

메시지를 수신하여 처리를 담당할 객체들을 하나의 연결 고리로 만들고, 실제로 요청을 처리하는

객체를 만날 때까지 계속해서 요청을 전달하게 한다.



#include <windows.h>

#include <tchar.h>

#include <memory>

#include <iostream>

#include <deque>

#include <list>

#include <vector>

#include <algorithm>

#include <iomanip>


class Handler

{

public:

typedef int Topic;

public:

explicit Handler (Handler *s=0, Topic t=0) : 

Successor_(s),

Topic_    (t)

{

}

virtual ~Handler ()

{

}

public:

virtual void HandleRequest(void)

{

if (Successor_)

{

Successor_->HandleRequest ();

}

else

{

std::cout << "Handler::HandleRequest() : no Successor_" << std::endl;

}

}

virtual void SetHandler (Handler *s=0, Topic t=0)

{

Successor_=s;

Topic_    =t;

}

protected:

Handler* Successor_;

Topic    Topic_;

};

class ConcreteHandler1 : public Handler

{

public:

ConcreteHandler1 (Handler *s=0, Topic t=0) : 

 Handler(s,t)

 {

 }

public:

virtual void HandleRequest(void)

{

if (Topic_==1)

{

std::cout << "ConcreteHandler1::HandleRequest()" << std::endl;

}

else

{

Handler::HandleRequest();

}

};

};

class ConcreteHandler2 : public Handler

{

public:

ConcreteHandler2 (Handler *s=0, Topic t=0) : 

 Handler(s,t)

 {

 }

public:

virtual void HandleRequest(void)

{

if (Topic_==2)

{

std::cout << "ConcreteHandler2::HandleRequest()" << std::endl;

}

else

{

Handler::HandleRequest();

}

};

};

class ConcreteChildHandler : public ConcreteHandler2

{

public:

ConcreteChildHandler (Handler *s=0, Topic t=0) : 

 ConcreteHandler2(s,t)

 {

 }

public:

virtual void HandleRequest(void)

{

if (Topic_==3)

{

std::cout << "ConcreteChildHandler::HandleRequest()" << std::endl;

}

else

{

ConcreteHandler2::HandleRequest();

}

};

};



int _tmain(int argc, _TCHAR* argv[])

{

Handler* handler1 = new Handler              ();

Handler* handler2 = new ConcreteHandler1     (handler1, 1);

Handler* handler3 = new ConcreteHandler2     (handler2, 1);

Handler* handler4 = new ConcreteChildHandler (handler3, 2);

Handler* handler5 = new ConcreteChildHandler (handler3, 3);

handler1->HandleRequest();

handler2->HandleRequest();

handler3->HandleRequest();

handler4->HandleRequest();

handler5->HandleRequest();

delete handler1;

delete handler2;

delete handler3;

delete handler4;

delete handler5;

return 0;

}

-> Handler::HandleRequest() : no Successor_
-> ConcreteHandler1::HandleRequest()
-> ConcreteHandler1::HandleRequest()
-> ConcreteHandler2::HandleRequest()
-> ConcreteChildHandler::HandleRequest()