這篇文章比較短,修改自 寫給你們看的設計模式之中介者中的例子
中介者模式的定義和目的自沒必要說, 參考上文便可. 本文針對實現方式作一個補充.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