这篇文章比较短,修改自 写给你们看的设计模式之中介者中的例子
中介者模式的定义和目的自没必要说, 参考上文便可. 本文针对实现方式作一个补充.ios
中介者模式增长了一个第三方对象(中介者)来控制两个对象(同事)间的交互. 有助于对彼此通讯的解耦, 毕竟他们并不须要关心对方的实现细节.segmentfault
例子中给出了ChatRoom
做为第三方中介者, 而User
做为真正的通讯对象, 每一个用户发送的消息其实是在ChatRoom
中进行了广播. 对于通讯的接耦有两种方式:设计模式
User
调用第三方对象的方法, 进行消息或者动做的传递, 好比上文中的实现即调用了ChatRoom
的ShowMessage
方法.这里针对第二点给出实现, 这里利用boost::signal2来实现ChatRoom
对消息体订阅, 各User
对象实例负责信息的发布.ide
#include <iostream> #include <string> #include <ctime> #include <iomanip> #include <boost/signals2/signal.hpp> using namespace std; using namespace boost::signals2; // Message struct EventMessage { virtual ~EventMessage() = default; virtual void showMessage() const = 0; }; struct ChatMessage : public EventMessage { string username; string message; ChatMessage(const string &username, const string &message) : username(username), message(message) {} void showMessage() const override { std::time_t now = std::time(nullptr); std::cout << std::put_time(std::localtime(&now), "%Y-%m-%d %H:%M:%S") << "[" << username << "]: " << message << std::endl; } }; // EventBus -> ChatRoom struct EventBus { signal<void(EventMessage *)> sig; EventBus() { sig.connect([](EventMessage *e){ ChatMessage *mess = dynamic_cast<ChatMessage *>(e); if(mess) { mess->showMessage(); }}); } }; // instance struct User { string name_; EventBus &event; User(const string &name_, EventBus &event) : name_(name_), event(event) { } void send(const string &message) { ChatMessage chatMessage(name_, message); event.sig(&chatMessage); } }; int main() { EventBus bus; User john("John Doe", bus); User jane("Jane Doe", bus); john.send("Hi, there!"); jane.send("Hey!"); }
当前的例子的业务模型实际比较简单, 若是业务变的复杂(好比还要支持私信便可定点sendMessage新增广播消息即每一个用户须要支持received), 若是继续使用方法传递,那么ChatRoom
为了和User
通讯,互相调用来调用去,很容易晕掉, 而只用经过订阅事件进行的数据传递,数据生产者和使用者在注册的时候就清晰明了,不容易出错.spa