Bir geri dönüşüm fabrikasındaki bantı düşünün. Bir nesne, banttan geçerken tipine ve şeklinde göre işçiler tarafından ayıklanır. Şöyle yapalım.
- İşçi bantta gördüğü nesneyi alıp metal mi diye kontrol eder. Eğer metalse kendi yanındaki kutuya atar. Nesne metal değilse nesneyi sonraki işçiye verir.
- İşçi plastik için
- İşçi ise cam nesneler için aynı işlemi uygular.

Chain of Responsibility (Sorumluluk zinciri) buna benzer bir şekilde çalışır. Karpuzların elden ele taşınması gibi nesneler, handlerdan handler’a taşınır. Tek fark eğer handler nesneyi kullanabiliyorsa onu alıp kullanır. Yoksa sonraki handler a atar.
/**
* The Handler interface declares a method for building the chain of handlers.
* It also declares a method for executing a request.
*/
#include <iostream>
#include <string>
#include <vector>
using namespace std;
class Handler {
public:
virtual Handler* SetNext(Handler* handler) = 0;
virtual std::string Handle(std::string request) = 0;
};
/**
* The default chaining behavior can be implemented inside a base handler class.
*/
class AbstractHandler : public Handler {
/**
* @var Handler
*/
private:
Handler* next_handler_;
public:
AbstractHandler() : next_handler_(nullptr) {
}
Handler* SetNext(Handler* handler) override {
this->next_handler_ = handler;
// Returning a handler from here will let us link handlers in a convenient
// way like this:
// $monkey->setNext($squirrel)->setNext($dog);
return handler;
}
std::string Handle(std::string request) override {
if (this->next_handler_) {
return this->next_handler_->Handle(request);
}
return {};
}
};
/**
* All Concrete Handlers either handle a request or pass it to the next handler
* in the chain.
*/
class MonkeyHandler : public AbstractHandler {
public:
std::string Handle(std::string request) override {
if (request == "Banana") {
return "Monkey: I'll eat the " + request + ".\n";
}
else {
return AbstractHandler::Handle(request);
}
}
};
class SquirrelHandler : public AbstractHandler {
public:
std::string Handle(std::string request) override {
if (request == "Nut") {
return "Squirrel: I'll eat the " + request + ".\n";
}
else {
return AbstractHandler::Handle(request);
}
}
};
class DogHandler : public AbstractHandler {
public:
std::string Handle(std::string request) override {
if (request == "MeatBall") {
return "Dog: I'll eat the " + request + ".\n";
}
else {
return AbstractHandler::Handle(request);
}
}
};
/**
* The client code is usually suited to work with a single handler. In most
* cases, it is not even aware that the handler is part of a chain.
*/
void ClientCode(Handler& handler) {
std::vector<std::string> food = { "Nut", "Banana", "Cup of coffee" };
for (const std::string& f : food) {
std::cout << "Client: Who wants a " << f << "?\n";
const std::string result = handler.Handle(f);
if (!result.empty()) {
std::cout << " " << result;
}
else {
std::cout << " " << f << " was left untouched.\n";
}
}
}
/**
* The other part of the client code constructs the actual chain.
*/
int main() {
MonkeyHandler* monkey = new MonkeyHandler;
SquirrelHandler* squirrel = new SquirrelHandler;
DogHandler* dog = new DogHandler;
monkey->SetNext(squirrel)->SetNext(dog);
/**
* The client should be able to send a request to any handler, not just the
* first one in the chain.
*/
std::cout << "Chain: Monkey > Squirrel > Dog\n\n";
ClientCode(*monkey);
std::cout << "\n";
std::cout << "Subchain: Squirrel > Dog\n\n";
ClientCode(*squirrel);
delete monkey;
delete squirrel;
delete dog;
return 0;
}
Chain: Monkey > Squirrel > Dog
Client: Who wants a Nut?
Squirrel: I'll eat the Nut.
Client: Who wants a Banana?
Monkey: I'll eat the Banana.
Client: Who wants a Cup of coffee?
Cup of coffee was left untouched.
Subchain: Squirrel > Dog
Client: Who wants a Nut?
Squirrel: I'll eat the Nut.
Client: Who wants a Banana?
Banana was left untouched.
Client: Who wants a Cup of coffee?
Cup of coffee was left untouched.


Leave a Reply