diff --git a/mediator/Mediator.cpp b/mediator/Mediator.cpp new file mode 100644 index 0000000..3d0e95b --- /dev/null +++ b/mediator/Mediator.cpp @@ -0,0 +1,120 @@ +/* + * C++ Design Patterns: Mediator + * Author: Jakub Vojvoda [github.com/JakubVojvoda] + * 2016 + * + * Source code is licensed under MIT License + * (for more details see LICENSE) + * + */ + +#include +#include + +class Mediator; + +/* + * Colleague classes + * each colleague communicates with its mediator whenever + * it would have otherwise communicated with another colleague + */ +class Colleague { +public: + Colleague(Mediator *m, unsigned int i) + : mediator(m), id(i) {} + + virtual ~Colleague() {} + + unsigned int getID() { + return id; + } + + virtual void send(std::string) = 0; + virtual void receive(std::string) = 0; + +protected: + Mediator *mediator; + unsigned int id; +}; + +class ConcreteColleague : public Colleague { +public: + ConcreteColleague(Mediator *m, unsigned int i) + : Colleague(m, i) {} + + void send(std::string msg); + + void receive(std::string msg) { + std::cout << "Message '" << msg << "' received by Colleague " << id << std::endl; + } +}; + +/* + * Mediator + * defines an interface for communicating with Colleague objects + */ +class Mediator { +public: + virtual ~Mediator() {} + + virtual void add(Colleague *c) = 0; + virtual void distribute(Colleague *sender, std::string msg) = 0; + +protected: + Mediator() {} +}; + +/* + * Concrete Mediator + * implements cooperative behavior by coordinating Colleague objects + * and knows its colleagues + */ +class ConcreteMediator : public Mediator { +public: + ~ConcreteMediator() { + for (unsigned int i = 0; i < colleagues.size(); i++) { + delete colleagues[i]; + } + colleagues.clear(); + } + + void add(Colleague *c) { + colleagues.push_back(c); + } + + void distribute(Colleague *sender, std::string msg) { + for (unsigned int i = 0; i < colleagues.size(); i++) { + if (colleagues.at(i)->getID() != sender->getID()) { + colleagues.at(i)->receive(msg); + } + } + } + +private: + std::vector colleagues; +}; + +void ConcreteColleague::send(std::string msg) { + std::cout << "Message '"<< msg << "' sent by Colleague " << id << std::endl; + mediator->distribute(this, msg); +} + + +int main() +{ + Mediator *mediator = new ConcreteMediator; + + Colleague *c1 = new ConcreteColleague(mediator, 1); + Colleague *c2 = new ConcreteColleague(mediator, 2); + Colleague *c3 = new ConcreteColleague(mediator, 3); + + mediator->add(c1); + mediator->add(c2); + mediator->add(c3); + + c1->send("Hi!"); + c3->send("Hello!"); + + delete mediator; + return 0; +} diff --git a/mediator/README.md b/mediator/README.md new file mode 100644 index 0000000..ce7868a --- /dev/null +++ b/mediator/README.md @@ -0,0 +1,12 @@ +## Mediator + +Mediator pattern has behavioral purpose and applies on objects. +The pattern defines an object that encapsulates how a set of objects interact. +It promotes loose coupling by keeping objects from referring to each +other explicitly, and it lets you vary their interaction independently. + +### When to use + +* a set of objects communicate in well-defined but complex ways +* reusing an object is difficult because it refers to and communicates with many other objects +* a behavior that's distributed between several classes should be customizable without a lot of subclassing \ No newline at end of file