#include <iostream>
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.
Returning a handler from here will let us link handlers in a convenient way like this:
$mouse->setNext($cat)->setNext($dog);
#include "Handler.h"
class AbstractHandler : public Handler {
private:
Handler *next_handler_;
public:
AbstractHandler() : next_handler_(nullptr) {
}
Handler *SetNext(Handler *handler) override {
this->next_handler_ = handler;
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.
The mouse take the chees.
#include "AbstractHandler.h"
class MouseHandler : public AbstractHandler {
public:
std::string Handle(std::string request) {
if (request == "Cheese") {
return "Mouse: I'll eat the " + request + ".\n";
} else {
return AbstractHandler::Handle(request);
}
}
};
The cat is addicted to Catnip.
#include "AbstractHandler.h"
class CatHandler: public AbstractHandler {
public:
std::string Handle(std::string request) {
if (request == "Catnip") {
return "Cat: I'll eat the " + request + ".\n";
} else {
return AbstractHandler::Handle(request);
}
}
};
The dog wants the bone.
#include "AbstractHandler.h"
class DogHandler : public AbstractHandler{
public:
std::string Handle(std::string request) {
if (request == "Bone") {
return "Dog: I'll eat the " + request + ".\n";
} else {
return AbstractHandler::Handle(request);
}
}
};
Let's put this all together in the main.cpp.
We first start with our includes.
#include <iostream> #include <vector> #include "Handler.h" #include "MouseHandler.h" #include "CatHandler.h" #include "DogHandler.h"Let's also create some ClientCode to hand passing out food or feeding the animales.
void ClientCode(Handler &handler) {
std::vector<std::string> food = {"Catnip", "Cheese","Bone", "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";
}
}
}
In the main method we declear some new animals and pass put food.
The client should be able to send a request to any handler, not just the first one in the chain.
int main() {
MouseHandler *mouse = new MouseHandler;
CatHandler *cat = new CatHandler;
DogHandler *dog = new DogHandler;
mouse->SetNext(cat)->SetNext(dog);
std::cout << "Chain: Cat > Mouse > Dog\n\n";
ClientCode(*mouse);
std::cout << "\n";
std::cout << "Subchain: Cat > Dog\n\n";
ClientCode(*cat);
delete mouse;
delete cat;
delete dog;
return 0;
}
Let's compile an run, we should get:
Chain: Cat > Mouse > Dog Client: Who wants a Catnip? Cat: I'll eat the Catnip. Client: Who wants a Cheese? Mouse: I'll eat the Cheese. Client: Who wants a Bone? Dog: I'll eat the Bone. Client: Who wants a Cup of coffee? Cup of coffee was left untouched. Subchain: Cat > Dog Client: Who wants a Catnip? Cat: I'll eat the Catnip. Client: Who wants a Cheese? Cheese was left untouched. Client: Who wants a Bone? Dog: I'll eat the Bone. Client: Who wants a Cup of coffee? Cup of coffee was left untouched.
The Ray Code is AWESOME!!!
wikipedia
Find Ray on:
youtube
The Ray Code
Ray Andrade
