动机
在面向对象的设计中,鼓励将行为封装到各自的对象中,这就会导致如果一个动作涉及多个类对象之间的互动时,往往导致类与类之间的关系错综复杂。显然,这不利于后续的维护和扩展。
中介者类似于“加一层”的思想,将涉及多个类对象之间的动作封装到中介者类中,由中介者进行协调控制,而其他的类对象只需要知道中介者这个类就可以了,执行动作时,不需要再去和其他类交互。
中介者形象上类似于一个货物中转中心,负责调配所有的中转方案。
示例
还是用货物中转举例,现在我们有以下的几种货物到达了中转站,但入口只有一个,需要决定谁先进去,如果让这几种货物协商,那么每个货物对象都需要知道对象的存在,这无疑增大了对象间的耦合性。
1 2 3 4 5
| class FruitGoods;
class ClothesGoods;
class SeafoodGoods;
|
于是我们选择让中介者来决定,所有货物到达后通知中介者,中介者再通知该货物等待多久后进入。
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
| std::random_device seed; std::default_random_engine eng(seed()); std::uniform_int_distribution<int> generator(1, 5);
class Goods;
class GoodsMediator { public: void registerGoods(Goods& goods) { m_goodslist.push_back(goods); }
int notify() { return generator(eng); }
private: std::vector<Goods> m_goodslist{}; };
class Goods { public: Goods(GoodsMediator& mediator) : m_mediator(mediator) { mediator.registerGoods(*this); }
virtual void waitEnter() { std::cout << "wait for " << m_mediator.notify() << " s\n";; }
protected: GoodsMediator& m_mediator; };
class FruitGoods : public Goods { public: FruitGoods(GoodsMediator& mediator) : Goods(mediator) { } void waitEnter() { cout << "fruit: "; Goods::waitEnter(); } };
class ClothesGoods : public Goods { public: ClothesGoods(GoodsMediator& mediator) : Goods(mediator) { } void waitEnter() { cout << "clothes: "; Goods::waitEnter(); } };
class SeafoodGoods : public Goods { public: SeafoodGoods(GoodsMediator& mediator) : Goods(mediator) { }
void waitEnter() { cout << "seafood: "; Goods::waitEnter(); } };
int main() { GoodsMediator mediator; FruitGoods fruit(mediator); ClothesGoods clothes(mediator); SeafoodGoods seafood(mediator);
fruit.waitEnter(); clothes.waitEnter(); seafood.waitEnter();
return 0; }
|
结果可能如下:
1 2 3
| fruit: wait for 3 s clothes: wait for 2 s seafood: wait for 4 s
|
通过加入了中介者这一层,货物之间的耦合性降低了,货物只需要知道中介者,并且将自己注册给中介者即可。
适用性
- 一组对象通过一些定义良好但复杂的方式进行通讯,产生的依赖关系过于混乱而难以理解。
- 一个对象需要和多个对象直接通信,导致这个对象难以复用。
- 希望定制一些涉及多个类的行为,但是又不想生成太多的子类。