设计模式——中介者模式

一 简介

用一个中介对象来封装一系列的对象交互,中介者使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。

二 使用场景

当对象之间的交互操作很多且每个对象的行为操作都依赖彼此时,为防止在修改一个对象的行为时,同时涉及修改很多其他对象的行为,可采用中介者模式,来解决紧耦合问题。该模式将对象之间的多对多关系变成一对多关系,中介者对象将系统从网状结构变成以调停者为中心的星形结构,达到降低系统的复杂性,提高可扩展性的作用。

三 UML图

在这里插入图片描述
中介者模式包括以下角色:

  • 抽象中介者(Mediator)角色:定义出同事对象到中介者对象的接口,其中主要方法是一个(或多个)事件方法。
  • 具体中介者(ConcreteMediator)角色:实现了抽象中介者所声明的事件方法。具体中介者知晓所有的具体同事类,并负责具体的协调各同事对象的交互关系。
  • 抽象同事类(Colleague)角色:定义出中介者到同事对象的接口。同事对象只知道中介者而不知道其余的同事对象。
  • 具体同事类(ConcreteColleague)角色:所有的具体同事类均从抽象同事类继承而来。实现自己的业务,在需要与其他同事通信的时候,就与持有的中介者通信,中介者会负责与其他的同事交互。

四 代码示例

小明的店铺主要是卖键盘和鼠标以及组装电脑,而顾客小红想要买一台组装电脑,但是由于卖电脑的店铺实在太多和里面水分太多,为了避免受骗,小红去找了一家信誉很好的中介来帮忙处理。

4.1 抽象同事类Colleague角色,用于下面店铺和顾客继承

abstract class Colleague {


    var name : String? = null
    var mediator:Mediator? = null

    constructor(name:String?,mediator: Mediator?){
        this.name = name
        this.mediator = mediator
    }

}

4.2 具体同事类:顾客和店铺

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")
    }

}

4.3 抽象中介者Mediator角色,提供一个联系的方法

abstract class Mediator {
    abstract fun constact(message:String?,colleague: Colleague)
}

4.4 具体中介者

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!!);
        }
    }
}

4.5 测试使用

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的配置信息,请查收...

五 优缺点

中介者模式的优点

  1. 松散耦合

中介者模式通过把多个同事对象之间的交互封装到中介者对象里面,从而使得同事对象之间松散耦合,基本上可以做到互补依赖。这样一来,同事对象就可以独立地变化和复用,而不再像以前那样“牵一处而动全身”了。

  1. 集中控制交互

多个同事对象的交互,被封装在中介者对象里面集中管理,使得这些交互行为发生变化的时候,只需要修改中介者对象就可以了,当然如果是已经做好的系统,那么就扩展中介者对象,而各个同事类不需要做修改。

  1. 多对多变成一对多

没有使用中介者模式的时候,同事对象之间的关系通常是多对多的,引入中介者对象以后,中介者对象和同事对象的关系通常变成双向的一对多,这会让对象的关系更容易理解和实现。

中介模式的缺点

  1. 中介者模式的一个潜在缺点是,过度集中化。如果同事对象的交互非常多,而且比较复杂,当这些复杂性全部集中到中介者的时候,会导致中介者对象变得十分复杂,而且难于管理和维护。

六 Android源码中的应用

  1. 锁屏功能的实现(Keyguard,keyguardViewMediator)
  2. Binder机制

有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就相当于一个中介者,协调各个服务端与客户端

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值