中介者模式(The Mediator Pattern)
在软件工程中,中介者模式定义了一个对象封装了一些列对象的交互.这种模式被认为是一个行为模式,因为它可以改变程序的运行行为。也可以看这里。
通常一个程序是由大量的类组成。所以相关逻辑和计算被分布在类间。然而,随着更多的类被应用到程序中,特别是在维护或重构期间,这些类之间的沟通和交互的问题可能会变得更为复杂。这使得程序难以阅读和维护。此外,程序可能变得难以改变,因为任何改变可能会影响其他类中的代码。通过中介模式,对象之间的通信被封装在一个中介对象中。对象不再彼此直接沟通,而是通过中介进行通信。这减少了沟通对象之间的依赖关系,从而降低耦合。
中介者模式确保了各个部分的松耦合,各个部分并没有明显的进行相互调用。反而所有的事情都有mediator实现。而且可以独立地改变它们之间的交互。为了使得对象间低耦合,中介者保持追踪所有对象的状态并且传输它们之间的通信。
飞机的飞行员接近或离开航站区域都是与控制塔进行交流而不是显式地与其它飞机上的飞行员沟通交流。谁能起飞或降落都是由控制台控制。但是重要的是,控制塔并不控制整个飞行,它只对航站区域进行控制。
具体实例
例子很简单:首先创建一个Mediator.swift文件,拥有以下内容:
1:一个Colleague类,包含了名字和中介者协议等属性,以及相关方法。
2:中介者协议(Mediator),该协议定义了相关接口用于Colleague之间的交互或通信。
3:一个信息中介者类(MessageMediator),该类实现Mediator接口并且协调Colleague之间的交互或通信,它知道所有的colleagues以及它们交流的目的。
4:具体的ConcreteColleague类处理信息。
class Colleague {
//名字和中介者协议属性
let name: String
let mediator: Mediator
init(name: String, mediator: Mediator) {
self.name = name
self.mediator = mediator
}
//在该类中发送信息,由中介者执行
func send(message: String) {
mediator.send(message: message, colleague: self)
}
func receive(message: String) {
assert(false, "Method should be overriden")
}
}
//Mediator:定义具体的接口用于Colleague之间的交互或通信
protocol Mediator {
func send(message: String, colleague: Colleague)
}
//MessageMediator:实现 Mediator接口并且协调Colleague之间的交互或通信。它知道所有的colleagues以及它们交流的目的。
class MessageMediator: Mediator {
private var colleagues: [Colleague] = []
//添加Colleague
func addColleague(colleague: Colleague) {
colleagues.append(colleague)
}
//向其他Colleague发送信息
func send(message: String, colleague: Colleague) {
for c in colleagues {
if c !== colleague { //for simplicity we compare object references
c.receive(message: message)
}
}
}
}
//ConcreteColleague:通过Mediator与其它Colleague交互
class ConcreteColleague: Colleague {
override func receive(message: String) {
print("Colleague \(name) received: \(message)")
}
}
测试部分如下:
override func viewDidLoad() {
super.viewDidLoad()
//创建发送信息协调者对象
let messagesMediator = MessageMediator()
//创建具体的两个同事对象,传入同事名称和信息协调者,当同事执行发送信息的时候该协调者用于内存操作信息的发送
let user0 = ConcreteColleague(name: "0", mediator: messagesMediator)
let user1 = ConcreteColleague(name: "1", mediator: messagesMediator)
//向信息协调者中加入同事
messagesMediator.addColleague(colleague: user0)
messagesMediator.addColleague(colleague: user1)
//user0发送信息,user1接受信息
user0.send(message: "Hello") // user1 receives message
}
适用性
1:对象间的交互虽定义明确而非常复杂,导致一组对象彼此相互依赖而且难以理解
2:因为对象引用了许多其他对象并与其通讯,导致对象难以复用
3:想要定制一个分布在多个类中的逻辑或行为,又不想生成太多子类
4:交互的公共行为,如果需要改变行为则可以增加新的中介者类
1:中国加入 WTO 之前是各个国家相互贸易,结构复杂,现在是各个国家通过 WTO 来互相贸易。
2:机场调度系统。
3:MVC 框架,其中C(控制器)就是 M(模型)和 V(视图)的中介者。
优缺点
优点: 1:降低了类的复杂度,将一对多转化成了一对一。
2:简化了对象之间的交互,各个类之间的解耦。
3:符合迪米特原则。
缺点: 在具体中介者类中包含了对象之间的交互细节,可能会导致具体中介者类非常复杂,过于庞大,使得系统难以维护。
中介者模式总结
中介者模式包装了一系列对象相互作用的方式,使得这些对象不必相互明显作用。从而是它们可以松散耦合。当某些对象之间的作用发生改变时,不会立即影响其他的一些对象,保证这些作用可以彼此独立的变化。中介者模式将多对多的相互作用转化为一对多的相互作用。中介者模式将对象的行为和协作抽象化,把对象在小尺度的行为上与其他对象的相互作用分开处理。
推荐博客:
1:中介者模式