用一个中介对象来封装一系列的对象交互,中介者使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。
当对象之间的交互操作很多且每个对象的行为操作都依赖彼此时,为防止在修改一个对象的行为时,同时涉及修改很多其他对象的行为,可采用中介者模式,来解决紧耦合问题。该模式将对象之间的多对多关系变成一对多关系,中介者对象将系统从网状结构变成以调停者为中心的星形结构,达到降低系统的复杂性,提高可扩展性的作用。
中介者模式包括以下角色:
小明的店铺主要是卖键盘和鼠标以及组装电脑,而顾客小红想要买一台组装电脑,但是由于卖电脑的店铺实在太多和里面水分太多,为了避免受骗,小红去找了一家信誉很好的中介来帮忙处理。
abstract class Colleague {
var name : String? = null
var mediator:Mediator? = null
constructor(name:String?,mediator: Mediator?){
this.name = name
this.mediator = mediator
}
}
class Customer(name:String?,mediator: Mediator?) : Colleague(name,mediator) {
var TAG = "Colleague"
/**
* 与中介者联系
*/
fun constact(message: String?) {
mediator!!.constact(message, this)
}
/**
* 获取信息
*/
fun getMessage(message: String) {
Log.d(TAG,"顾客:$name, 获得信息:$message")
}
}
class Shop(name:String?,mediator: Mediator?):Colleague(name,mediator) {
var TAG = "Colleague"
/**
* 与中介者联系
*/
fun constact(message: String?) {
mediator!!.constact(message, this)
}
/**
* 获取信息
*/
fun getMessage(message: String) {
Log.d(TAG,"店铺:$name, 获得信息:$message")
}
}
abstract class Mediator {
abstract fun constact(message:String?,colleague: Colleague)
}
class MediatorStructure:Mediator() {
private val customer: Customer? = null
private val shop: Shop? = null
override fun constact(message: String?, colleague: Colleague) {
if(colleague is Customer){
//顾客来询问,中介去问店铺,店铺获得消息
shop?.getMessage(message!!);
}
else{
//店铺回复,中介通知顾客,顾客获得消息
customer?.getMessage(message!!);
}
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
var mediator = MediatorStructure()
var customer = Customer("顾客",mediator)
var shop = Shop("书店",mediator)
customer.constact("我想要组装一台电脑,价位在5k左右")
shop.constact("好的!这是5k的配置信息,请查收...")
}
输出结果:
店铺:小明, 获得信息:我想要组装一台电脑,价位在5k左右
顾客:小红, 获得信息:好的!这是5k的配置信息,请查收...
中介者模式的优点
中介者模式通过把多个同事对象之间的交互封装到中介者对象里面,从而使得同事对象之间松散耦合,基本上可以做到互补依赖。这样一来,同事对象就可以独立地变化和复用,而不再像以前那样“牵一处而动全身”了。
多个同事对象的交互,被封装在中介者对象里面集中管理,使得这些交互行为发生变化的时候,只需要修改中介者对象就可以了,当然如果是已经做好的系统,那么就扩展中介者对象,而各个同事类不需要做修改。
没有使用中介者模式的时候,同事对象之间的关系通常是多对多的,引入中介者对象以后,中介者对象和同事对象的关系通常变成双向的一对多,这会让对象的关系更容易理解和实现。
中介模式的缺点
有3个非常重要的组件ServiceManager,BinderDriver和BpBinder,其中BpBinder是Binder的一个代理角色,其提供IBinder接口给各个客户端服务使用,这三者就扮演了一个中介者的角色。当手机启动后,ServiceManager会先向Binder Driver进行注册,注意,这里ServiceManager虽然是一个特殊的服务,但毕意还是一个服务,其特殊性在干,它在 Binder Driver中是最先被注册的,其注册ID为0,当其他的服务想要注册到BinderDriver时,会先通过这个0号ID获取到ServiceManager所对应的IBinder接口,该接口实质上的实现逻辑是由BpBinder实现的,获取到对应的接口后就回调用其中的transact方法,此后就会在BinderDriver中新注册一个ID1来对应这个服务,如果有客户端想要使用这个服务,那么,它先会像BinderDriver一样获取到ID为0的接口,也就是 ServiceManager所对应的接口,并调用其transact方法要求连接到刚才的服务,这时候Binder Driver就会将ID为1的服务回传给客户端并将相关消息反馈给ServiceManager完成连接。这里 ServiceManager和BinderDriver就相当于一个中介者,协调各个服务端与客户端