一、什么是设计模式
设计模式是为特定场景下的问题而定制的解决方案。特定场景指问题所在的重复出现的场景,问题指特定环境下你想达成的目标。同样的问题在不同的环境下会有不同的限制和挑战。定制的解决方案是指在特定环境下克服了问题的限制条件而达成目标的一种设计。
二、设计模式的分类
设计模式分为三种类型,共23种。
创建型模式:单例模式、抽象工厂模式、建造者模式、工厂模式、原型模式。
结构型模式:适配器模式、桥接模式、装饰模式、组合模式、外观模式、享元模式、代理模式。
行为型模式:模版方法模式、命令模式、迭代器模式、观察者模式、中介者模式、备忘录模式、解释器模式(Interpreter模式)、状态模式、策略模式、职责链模式(责任链模式)、访问者模式。
三、场景介绍
面向对象的设计鼓励把行为分散到不同对象中,这种分散可能导致对象之间的相互关联。在最糟糕的情况下,所有对象都彼此了解并相互操作。
虽然把行为分散到不同对象增强了可复用性,但是增加的相互关联又减少了获得的益处。增加的关联使得对象很难或不能在不依赖其他对象的情况下工作。应用程序的整体行为可能难以进行任何重大修改,因为行为分布于许多对象。于是结果可能是创建越来越多的子类,以支持应用程序中的任何新行为。
四、我们来看一个现实的场景
机场有很多的飞机,每个飞机都要起飞和降落,为了保证能够安全的起飞和降落,飞机之间就需要进行通信,来报告自己的位置的变化。他们之间的通信如下图所示:
代码示例1
五、中介者模式定义
中介者模式(Mediator Pattern):定义一个中介对象来封装一系列对象之间的交互。中介者使各个对象不需要显示地相互引用,从而使其耦合性松散,而且可以独立地改变他们之间的交互。
六、模式结构
1.Mediator:抽象中介者。在里面定义各个同事之间交互需要的方法,可以是公共的通信方法,也可以是小范围的交互方法。
2.ConcreteMeditor:具体中介者。它需要了解并维护各个同事对象,并负责具体的协调各同事对象的交互关系。
3.同事类:如果一个对象会影响其他的对象,同时也会被其他对象影响,那么这两个对象称为同事类。在类图中,同事类只有一个,这其实是现实的省略,在实际应用中,同事类一般由多个组成,他们之间相互影响,相互依赖。同事类越多,关系越复杂。并且,同事类也可以表现为继承了同一个抽象类的一组实现组成。在中介者模式中,同事类之间必须通过中介者才能进行消息传递。
Colleague:抽象同事类,主要约束同事对象的类型,并实现一些具体同事类之间的公共功能,比如,每个具体同事类都应该知道中介者对象,也就是具体同事类都会持有中介者对象,都可以到这个类里面。
4.ConcreteColleague:具体同事类,实现自己的业务,需要与其他同事通信时候,就与持有的中介者通信,中介者会负责与其他同事类交互。
七、时序图
八、上述场景使用中介者模式
使用中介者模式,我们可以在上述飞机飞机通信的场景中加入控制中心,每个飞机只需要向控制中心发送消息,之后就不用管了,与其他飞机的交互交由控制中心来控制,如下图所示:
代码示例2
九、中介者承担两方面的职责
从上述列子中我们可以看出中介者担任的职责:
中转作用(结构性):通过中介者提供的中转作用,各个同事对象就不再需要显式引用其他同事,当需要和其他同事进行通信时,通过中介者即可。该中转作用属于中介者在结构上的支持。
协调作用(行为性):中介者可以更进一步的对同事之间的关系进行封装,同事可以一致地和中介者进行交互,而不需要指明中介者需要具体怎么做,中介者根据封装在自身内部的协调逻辑,对同事的请求进行进一步处理,将同事成员之间的关系行为进行分离和封装。该协调作用属于中介者在行为上的支持。
十、模式的优缺点
模式的优点
1.松散耦合
中介者模式通过把多个同事对象之间的交互封装到中介对象里面,从而使得同时对象之间松散耦合,基本上可以做到互不依赖。这样一来,同时对象就可以独立的变化和复用,不再“牵一发动全身”
2.集中控制交互
多个同事对象的交互,被封装在中介者对象里面集中管理,使得这些交互行为发生变化的时候,只需要修改中介者就可以了。
3.多对多变为一对多
没有中介者模式的时候,同事对象之间的关系通常是多对多,引入中介者对象后,中介者和同事对象的关系通常变为双向的一对多,这会让对象的关系更容易理解和实现。
模式的缺点
过多集中化
如果同事对象之间的交互非常多,而且比较复杂,当这些复杂性全都集中到中介者的时候,会导致中介者对象变的十分复杂,而且难于维护和管理。
十一、何时使用中介者模式
1.对象间的交互虽定义明确然而非常复杂,导致一组对象彼此依赖而且难以理解。
2.因为对象引用了许多其他对象并与其通讯,导致对象难以复用。
3.想要定制一个分布在多个类中的逻辑或行为,又不想生成太多的子类。
十二、中介者模式使用注意事项
中介者模式很好用,也很容易被滥用。一般对象之间简单关系是合理的可以不使用中介者模式。
只有对于那种对象之间是网状结构的关系,才会考虑使用中介者模式。可以将网状结构变为星状结构,使对象之间的关系变的清晰一些。
当系统出现了多对多交互复杂的对象群时,先不急于使用中介者模式,而是思考一下是不是系统设计有问题.
十三、中介者模式的实际应用(MVC)
1.MVC中的C(controller)就是一个中介者,它的作用就是把M和V隔离开,协调M和V协同工作,把M运行的结果和V代表的视图融合成一个前端可以展示的页面,减少M和V的依赖关系。
2.iOS中的UINavigationController就是一个中介者,他来管理视图的跳转。