中介者模式
中介者模式:用一个中介对象来封装一系列的对象交互,使得这些对象之间不需要显式地互相引用,从而松散这些对象间的耦合。
其实如果使用.NET的WinForm或WebFom做开发的话,我们经常会用到中介者模式。而这个中介者就是Form窗体。试想一下,如果我们在Form窗体里拖了俩个控件,一个Label,一个Button,我们想点击Button的时候改变Label的Text属性。想必大家都觉得很简单。但实际上,我们拖动这俩控件到Form上时,是new了俩实例在Form里面,然后在Button的Click事件所注册的方法里面获取Label实例,然后设置Label的Text的属性。而Button的Click事件所注册的方法是位于Form里的,所以Label与Button的交互是在Form里交互的。试想一下,如果在Button里面new 一个Label实例,然后在Button里对Label设置Text属性,是不可能的,因为这里只是与Label交互,如果与很多控件交互,难道要在Button里new 出所有控件实例不成?如果所有控件的交互都相互依赖的话,那将是很恐怖的!
我们平常用的电脑也有中介者模式的体现,主板是中介者,CD光驱、CPU、声卡、显卡等都是同事类。光驱读取光盘上的数据,然后告诉主板,主板把得到的数据交给CPU处理,CPU处理完了,告诉主板,主板将处理完的数据分别交给显卡和声卡,由它们显示视频和发出声音。
我们来看一下标准的中介者模式的结构图:
广义中介者:实际上标准的中介者结构在实际开发中并不实用或理想。而中介者模式实现的是封装对象间的交互,不必拘泥于标准的中介者模式结构,标准结构限制很多,导致能完全按照标准使用的中介者模式的地方不是很多。
比如:1.Collage父类没必要,实际开发中很多交互的对象本身没有公共父类。 2.同事类必须持有中介者对象吗?+mediator:Mediator,由于中介者是用来封装同事对象间的交互的,其本身一般是没有状态需要维护的,所以可以将中介者MotherBoard实现成单例。 3.中介者必须完全作为属性这样持有所有的同事类吗?而且有的方法可能需要的同事类实例的状态并不是当初通过属性获取的,所以其实可以根据具体情况,通过方法传递,或在方法里new一个等。 4.如果不需要扩展中介者,那么中介者接口Mediator是不需要的。
下面,用广义中介者代码来实现看视频的例子:
public class CDDriver { //读取cd数据,并将数据交给主板与其他同事类交互 public void readCD() { string data=“我是读到的视频数据,我是读到的音频数据”; MotherBoard.Instance().CDDataToCPU(data); } } public class MotherBoard { private static MotherBoard motherBoard=new MotherBoard(); public static MotherBoard Instance() { return motherBoard; } //将CD数据传给CPU public void CDDataToCPU(string data) { CPU cpu =new CPU(); cpu.CPUDealCDData(data); VideoDataToVideoCard(cpu.videoData); SoundDataToSoundCard(cpu.soundData); } //将视频数据传给显卡 public void VideoDataToVideoCard(string data) { new VideoCard().ShowVideo(data); } //将声音数据传给声卡 public void SoundDataToSoundCard(string data) { new SoundCard().ShowSound(data); } } publiic class CPU { public string videoData; public string soundData; //CPU处理CD数据 public void CPUDealCDData(string data) { //处理cd数据,将其分离为视频数据和声音数据 } } public class VideoCard { //播放视频 public void ShowVideo(string data) { } } public class SoundCard { //播放声音 public void ShowSound(string data) { } }
中介者模式的本质:封装交互