当我们有N个类需要互相沟通时,一对一的方式建立的连接数量为 N*(N-)/2 ,耦合性太高。我们应该建立一个中间节点,所有人通过这个中间节点来进行沟通,这就是中介者模式
比如国家与国家间进行交流时,建立一个联合国,大家通过这个中间人来发表声明,这时我们先抽象出一个国家基类,它定义了与中间者联合国交流的接口
1 2 3 4 5 6 7 8 9 10 11 12 13 14 class UnitedNation ;class AbstructCountry {public : virtual void sendMsg (Country target, std::string msg) = 0 ; virtual void GetMsg (Country from, std::string msg) = 0 ; virtual ~AbstructCountry () {} void SetUnion (UnitedNation *u) { m_u = u; } Country m_c; protected : UnitedNation* m_u; };
联合国类提供一个接受消息的接口,以及addMember函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 class UnitedNation {public : void addMember (AbstructCountry* country) { m_members[country->m_c] = country; country->SetUnion (this ); } void PushMsg (Country from, Country to, std::string msg) { if (to == Country::ALL) { for (auto &item : m_members) { if (item.first == from) { continue ; } item.second->GetMsg (from, msg); } } else { m_members[to]->GetMsg (from, msg); } } private : std::unordered_map<Country, AbstructCountry*> m_members; };
此时,每个国家类都可以继承 AbstructCountry ,重写发送消息和接受消息的接口,发送消息要把声明传递给联合国对象 m_u。
整体代码如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 #include <csignal> #include <iostream> #include <string> #include <cstdint> #include <unordered_map> enum class Country : uint8_t { CN, RU, US, ALL, }; std::string enum2str (Country c) { switch (c) { case Country::CN: return "中国" ; case Country::RU: return "俄罗斯" ; case Country::US: return "美国" ; case Country::ALL: return "所有与会国" ; } } class UnitedNation ;class AbstructCountry {public : virtual void sendMsg (Country target, std::string msg) = 0 ; virtual void GetMsg (Country from, std::string msg) = 0 ; virtual ~AbstructCountry () {} void SetUnion (UnitedNation *u) { m_u = u; } Country m_c; protected : UnitedNation* m_u; }; class UnitedNation {public : void addMember (AbstructCountry* country) { m_members[country->m_c] = country; country->SetUnion (this ); } void PushMsg (Country from, Country to, std::string msg) { if (to == Country::ALL) { for (auto &item : m_members) { if (item.first == from) { continue ; } item.second->GetMsg (from, msg); } } else { m_members[to]->GetMsg (from, msg); } } private : std::unordered_map<Country, AbstructCountry*> m_members; }; class China : public AbstructCountry {public : China (){ m_c = Country::CN; } void sendMsg (Country target, std::string msg) override { std::cout << "中国向" << enum2str(target) << "发表声明:" << msg << std::endl; m_u->PushMsg (m_c, target, msg); } void GetMsg (Country from, std::string msg) override { std::cout << "中国收到来自" << enum2str(from) << "的声明:" << msg << std::endl; } }; class Russia : public AbstructCountry {public : Russia () { m_c = Country::RU; } void sendMsg (Country target, std::string msg) override { std::cout << "俄罗斯向" << enum2str(target) << "发表声明:" << msg << std::endl; m_u->PushMsg (m_c, target, msg); } void GetMsg (Country from, std::string msg) override { std::cout << "俄罗斯收到来自" << enum2str(from) << "的声明:" << msg << std::endl; } }; class USA : public AbstructCountry {public : USA () { m_c = Country::US; } void sendMsg (Country target, std::string msg) override { std::cout << "美国向" << enum2str(target) << "发表声明:" << msg << std::endl; m_u->PushMsg (m_c, target, msg); } void GetMsg (Country from, std::string msg) override { std::cout << "美国收到来自" << enum2str(from) << "的声明:" << msg << std::endl; } }; int main () { UnitedNation un; AbstructCountry* cn = new China (); AbstructCountry* ru = new Russia (); AbstructCountry* us = new USA (); un.addMember (cn); un.addMember (ru); un.addMember (us); std::cout << "==========================" << std::endl; us->sendMsg (Country::ALL, "我要制裁俄罗斯" ); std::cout << "==========================" << std::endl; us->sendMsg (Country::CN, "你不要购买俄罗斯的商品" ); std::cout << "==========================" << std::endl; cn->sendMsg (Country::ALL, "希望世界和平" ); std::cout << "==========================" << std::endl; ru->sendMsg (Country::US, "放马过来" ); delete cn; delete ru; delete us; return 0 ; }