<?php

	/**
	 * 3.8 中介者模式
	 * 	定义:
	 * 		用一个中介对象来封装一系列的对象交互。中介
	 * 		者使各对象不需要显式的相互引用,从而使其耦
	 * 		合松散,而起可以独立的改变它们之间的交互。
	 * 		
	 * 	角色:
	 * 		1. 抽象中介者(Mediator)类
	 * 			职责:定义了同事对象到中介者对象的接口
	 * 		2. 具体中介者类
	 * 			职责:实现抽象类的方法,它需要知道所有
	 * 				  具体同事类,并从具体同事接收消息
	 * 				  ,向具体同事对象发出命令。
	 * 		3. 抽象同事(Colleague)类
	 * 			职责:
	 * 		4. 具体同事类
	 * 			职责:每个具体同事只知道自己的行为,而
	 * 				  不了解其他同事类的情况,但它们却
	 * 				  都认识中介者对象。	
	 * 		
	 * 	优点:
	 * 	 	1. 中介者Mediator的出现减少了各个同事Colleague
	 * 	 	   的耦合使得可以独立的改变和复用各个Colleague
	 * 	 	   类和Mediator;
	 * 	 	2. 由于把对象如何协作进行了抽象,将中介作为
	 * 	 	   一个独立的概念并将其封装在一个对象中,这样
	 * 	 	   关注的对象就从对象各自本身的行为转移到他们
	 * 	 	   之间的交互上来,也就是站在一个更宏观的角度
	 * 	 	   去看待系统。
	 *
	 * 	缺点:
	 * 		1. 当具体的同事类越来越多时,系统就比较难于维护了。
	 *
	 *	使用场景:
	 *		1. 一组对象以定义良好但是复杂的方式进行通信。产生
	 *		   的相互依赖关系结构混乱且难以理解时;
	 *		2. 一个对象引用其他很多对象并且直接与这些对象通信
	 *		3. 想定制一个分布在多个类中的行为,而又不想生成太
	 *		   多的子类。
	 *
	 * 
	 */
	header('content-type:text/html;charset=utf8');

	//抽象中介者
	abstract class Mediator{
		//定义一个抽象的发送消息方法,
		//得到同事对象和发送信息。
		abstract public function send($message,Colleague $colleague);
	}
	//具体中介者类
	class ConcreteMediator extends Mediator{
		private $colleague1;
		private $colleague2;
		public function addColleague1(ConcreteColleague1 $colleague1){
			$this->colleague1=$colleague1;			
		}
		public function addColleague2(ConcreteColleague2 $colleague2){
			$this->colleague2=$colleague2;
		}
		public function send($message,Colleague $colleague){
			if($colleague == $this->colleague1){
				$this->colleague2->notify($message);
			}else{
				$this->colleague1->notify($message)	;			
			}
		}
	}
	//抽象同事类
	abstract class Colleague{
		protected $mediator;
		//构造方法,得到中介者对象
		public function __construct(Mediator $mediator){
			$this->mediator=$mediator;
		}
	}

	//具体同事类
	class ConcreteColleague1 extends Colleague{
		public function send($message){
			//表示消息是由中介者代替发送的,
			//并且发送的的人是$this
			$this->mediator->send($message,$this);
		}
		//注意:方法notify的消息($message)是
		//		由另外一个同事发给他的消息;而
		//		方法send中的消息($message)是
		//		他自己要发出的消息。
		public function notify($message){
			echo '同事1得到的信息是:'.$message;
		}
	}
	class ConcreteColleague2 extends Colleague{
		public function send($message){
			$this->mediator->send($message,$this);
		}
		public function notify($message){
			echo '同事2得到的消息是:'.$message;
		}
	}

	//客户端
	//生成中介
	$mediator=new ConcreteMediator();		
	//生成发起消息的对象
	$colleague1=new ConcreteColleague1($mediator);
	$colleague2=new ConcreteColleague2($mediator);
	//将所有要发送消息的人添加到中介里
	$mediator->addColleague1($colleague1);
	$mediator->addColleague2($colleague2);
	//双方开始通过中介发送消息
	$colleague1->send('我是张三,你到家了吗?');
	$colleague2->send('还没到,还在车上?');
	
?>