概要
基于OO来设计经常会产生很多对象,而这些对象之间又会相互交互影响,所以经常会导致对象间的紧耦合,为了能够避免这种紧耦合,就需要一种机制让每个对象能够很方便的跟其他对象交互而又不需要跟这些对象交叉耦合在一起。怎么做?有人会说Observer模式不就是解决这类问题的吗?确实,一点没错,Observer模式关注的是被观察主题Subject和观察者Observer之间的交互。而本文将介绍的Mediator模式也是为了解决这类问题,但关注点跟Observer有所不同,我们来看看它是怎么做的。
基于OO来设计经常会产生很多对象,而这些对象之间又会相互交互影响,所以经常会导致对象间的紧耦合,为了能够避免这种紧耦合,就需要一种机制让每个对象能够很方便的跟其他对象交互而又不需要跟这些对象交叉耦合在一起。怎么做?有人会说Observer模式不就是解决这类问题的吗?确实,一点没错,Observer模式关注的是被观察主题Subject和观察者Observer之间的交互。而本文将介绍的Mediator模式也是为了解决这类问题,但关注点跟Observer有所不同,我们来看看它是怎么做的。
目的
定义一个对象来封装其他一组对象间的交互行为,减少其他对象间的耦合度,让这些对象间的交互可以更独立地被修改。
实例
考虑一个UI应用的例子,假设我们的界面需要一些窗口来显示某些内容,比如显示产品介绍视频的窗口,显示产品图片的窗口,显示跟产品视频配套的介绍文字的窗口,显示跟产品图片配套的介绍文字的窗口等。
考虑一个UI应用的例子,假设我们的界面需要一些窗口来显示某些内容,比如显示产品介绍视频的窗口,显示产品图片的窗口,显示跟产品视频配套的介绍文字的窗口,显示跟产品图片配套的介绍文字的窗口等。
再假设有这样的需求:
1.在显示视频窗口时需要同步显示视屏对应的文字窗口,同时还要发送消息给图片窗口。
2.显示图片窗口时需要同步显示图片对应的文字窗口同时还要发送消息给视频窗口。
因为需要同步显示和传递消息,所以不同窗口间就需要进行交互,虽然这种交互很简单,但我们还是考虑用Mediator模式来处理,看看它是怎么解除这些窗口间的耦合。
使用Mediator来处理的类图和代码如下:
class Mediator { virtual void VideoSync() = 0; virtual void ImageSync() = 0; }; class Dialog { public: Dialog(Mediator* md) { mMediator = md; } void SendMessage() { ...... } virtual void Show() = 0; protected: Mediator* mMediator; }; class TxtDialog : public Dialog { public: virtual void Show() { ...... } }; class VideoDialog : public Dialog { public: virtual void Show() { ...... mMediator->VideoSync(); } }; class ImageDialog : public Dialog { public: virtual void Show() { ...... mMediator->ImageSync(); } }; class SyncMediator : public Mediator { public: ...... virtual void VideoSync() { mVideoTxt->Show(); mImage->SendMessage(); } virtual void ImageSync() { mImageTxt->Show(); mVideo->SendMessage(); } private: TxtDialog* mImageTxt; TxtDialog* mVideoTxt; ImageDialog* mImage; VideoDialog* mVideo; };
从实现来看, 不管是Video窗口还是Image窗口都不需要去关注跟其他窗口间处理的细节,把交互处理全部转交给了SyncMediator来做,而在SyncMediator中则封装了所有窗口间的交互工作,提供方法给窗口类使用。
应用
在实际开发中,Mediator模式的应用虽然很常见但是普遍程度以及受认可程度却远不如Observer模式等,原因就是Mediator模式的缺点跟优点一样非常明显。
优点大家应该已经都能看出来了,首先把很多逻辑都归结到Mediator类,使代码逻辑更简单而易于理解,其次降低了对象间的耦合程度,第三统一了对象间的交互规则。那么缺点呢?总结来说就一点,那就是过多的逻辑归结与一处,往往会使Mediator过于复杂,降低其他对象耦合的同时却使Mediator本身难以理解和维护,所以选用的时候需要慎重。