中介者模式:

  在现实生活中,有很多中介者模式的身影,例如QQ游戏平台,聊天室、QQ群、短信平台和房产中介。不论是QQ游戏还是QQ群,它们都是充当一个中间平台,QQ用户可以登录这个中间平台与其他QQ用户进行交流,如果没有这些中间平台,我们如果想与朋友进行聊天的话,可能就需要当面才可以了。电话、短信也同样是一个中间平台,有了这个中间平台,每个用户都不要直接依赖与其他用户,只需要依赖这个中间平台就可以了,一切操作都由中间平台去分发。中介者模式,定义了一个中介对象来封装一系列对象之间的交互关系。中介者使各个对象之间不需要显式地相互引用,从而使耦合性降低,而且可以独立地改变它们之间的交互行为。

中介者模式的角色:

  1. 抽象中介者(Mediator):定义了同事对象到中介者对象的接口。
  2. 具体中介者(ConcreteMediator):实现抽象类的方法,它需要知道具体的同事类并从具体同事类接受消息,向具体同事对象发出命令。
  3. 抽象同事类(Colleague):定义同事类的接口,保存中介者对象,提供同事对象交互的抽象方法,实现所有相互影响的同事类的公共功能。
  4. 具体同事类(ConcreteColleague):每个具体同事类只知道自己的行为,而不了解其他同事类的情况,但它们认识中介者对象。

优点:

  1. 简化了对象之间的关系,将系统的各个对象之间的相互关系进行封装,将各个同事类解耦,使得系统变为松耦合。
  2. 提供系统的灵活性,使得各个同事对象独立而易于复用。

缺点:

  1. 中介者模式中,中介者角色承担了较多的责任,所以一旦这个中介者对象出现了问题,整个系统将会受到重大的影响。
  2. 新增加一个同事类时,不得不去修改抽象中介者类和具体中介者类,此时可以使用观察者模式和状态模式来解决这个问题。

中介者使用的场景:

  1. 一组定义良好的对象,现在要进行复杂的相互通信。
  2. 想通过一个中间类来封装多个类中的行为,而又不想生成太多的子类。

区别:

与观察者模式区别:

中介者模式主要是起到一个协调的作用,它知道所有的同事类且同事类含有中介者对象,即我有事通知你,你帮我协调一下。而观察者模式侧重在当一个对象的状态发生变化时,能够自动通知其他关联对象,自动刷新对象状态。

eg:

//抽象同事类
class Colleague {
protected :
	Mediator *mediator;

public:
	Colleague(Mediator* m) { mediator = m; }
	virtual void Sent(string message) = 0;
};


//具体同事类
class ConcreteColleague1 :public Colleague {
public:
	ConcreteColleague1(Mediator* m) : Colleague(m) {}
	void Sent(string message) { mediator->Send(message, this); }
	void Notify(string message) { cout << "同事1得到消息:" << message << endl; }
};

class ConcreteColleague2 :public Colleague {
public:
	ConcreteColleague2(Mediator* m) : Colleague(m) {}
	void Sent(string message) { mediator->Send(message, this); }
	void Notify(string message) { cout << "同事2得到消息:" << message << endl; }
};
//-----------------------------------------------------
//抽象中介者类
class Mediator {
public:
	virtual void Send(string message, Colleague *colleague) = 0;
};


//具体中介者类
class Concretemediator :public Mediator {
private:
	ConcreteColleague1* colleague1;
	ConcreteColleague2* colleague2;

public:
	void SetColleague1(Colleague* pColleague){
		colleague1 = dynamic_cast<ConcreteColleague1*>(pColleague);
	}
	void SetColleague2(Colleague * pColleague){
		colleague2 = dynamic_cast<ConcreteColleague2*>(pColleague);
	}

	void Send(string message, Colleague* colleague){
		if (colleague == colleague1)
			colleague2->Notify(message);
		else if (colleague == colleague2)
			colleague1->Notify(message);
	}
};

//-----------------------------------------------------
//use
	Concretemediator* mediator = new Concretemediator();
	
	ConcreteColleague1* colleague1 = new ConcreteColleague1(mediator);	//让他俩认识一下中介
	ConcreteColleague2* colleague2 = new ConcreteColleague2(mediator);

	mediator->SetColleague1(colleague1);	//让中介认识一下他俩
	mediator->SetColleague2(colleague2);

	colleague1->Sent("有男朋友没?");
	colleague2->Sent("有了");