25.世界需要和平 - 中介者模式 (大话设计模式Kotlin版)

世界需要和平

  • 国际形式错综复杂,国与国之间有时候因为利益摩擦、主权问题引发矛盾,进而发动战争。战争终究不可避免给人民带来无法弥补的伤痛!各个国家代表的利益不同,矛盾冲突是难免的。为了更好的维护国际关系,调和各个国家间的矛盾,催生了联合国:由各个国家的代表组成,维护国际和平与安全,解决国间经济、社会、文化、人道主义性质的问题。联合国的成立后,地球至二战后没有波及世界范围的战争,它对世界和平的贡献不可估量。

  • 国与国之间的关系类似于不同对象与对象之间的关系,那么就要求对象之间需知晓其他所有对象。一般为增加系统的可复用性,通常将其分割成许多对象,但是对象之间的相互关联又会降低其可复用性。因为大量的对象连接使得一个对象不可能在没有其他对象的支持下工作,系统表现为一个不可分割的整体,对系统行为的任何改动都极其困难。

  • 要解决上述问题,我们可以为系统增加一个‘联合国’的中介角色,对象与对象之间通过该中介进行通信,正如 迪米特法则如果两个类不必彼此直接通信,那么这两个类就不应当直接的相互作用。如果其中一个类需要调用另外一个类的某个方法的话,可以通过第三者转发这个调用。

  • 没有联合国的错综复杂的国际关系(仅为了参考)
    没有联合国的国际关系

  • 成立联合国后的国际关系(仅为了解释中介者的作用)
    成立联合国后的国际关系

中介者模式简介

定义

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

UML图

中介者模式UML图

代码实现

  • 举一个聊天例子来应用这个模式:同事A与同事B经常在上班摸鱼,通过wechat进行聊天,wechat在这里就是他们俩聊天的中介平台。

Mediator 抽象中介者类

/**
 * @create on 2020/6/7 22:22
 * @description 抽象中介者
 * @author mrdonkey
 */
abstract class Mediator {
    /**
     * 定义一个抽象的转发消息的方法,得到同事对象和转发消息
     */
    abstract fun forward(msg: String, colleague: Colleague)
}

Colleage 抽象同事类

/**
 * @create on 2020/6/7 22:23
 * @description 抽象同事类 [mediator] 构造方法,得到中介者对象
 * @author mrdonkey
 */
abstract class Colleague(private val mediator: Mediator) {
    /**
     * 发送消息
     */
    abstract fun send(msg: String)

    /**
     * 接收消息
     */
    abstract fun receive(msg: String)
}

ConcreteMediator 具体中介者类

/**
 * @create on 2020/6/7 22:29
 * @description 具体的中介者
 * @author mrdonkey
 */
class ConcreteMediator : Mediator() {
    var colleagueA: Colleague? = null
    var colleagueB: Colleague? = null

    /**
     * 判断消息的来源,并转发给对应的同事
     */
    override fun forward(msg: String, colleague: Colleague) {
        when (colleague) {
            colleagueA -> {
                colleagueB?.receive(msg)
            }
            colleagueB -> {
                colleagueA?.receive(msg)
            }
        }
    }
}

ConcreteColleagueA 具体同事A

/**
 * @create on 2020/6/7 22:37
 * @description 具体同事A
 * @author mrdonkey
 */
class ConcreteColleagueA(private val mediator: Mediator) : Colleague(mediator) {

    /**
     * 发送消息通过中介者进行转发
     */
    override fun send(msg: String) {
        mediator.forward(msg, this)
    }

    override fun receive(msg: String) {
        println("${this::class.java.simpleName}:收到消息--->$msg")
    }
}

ConcreteColleagueB 具体同事B

/**
 * @create on 2020/6/7 22:37
 * @description
 * @author mrdonkey
 */
class ConcreteColleagueB(private val mediator: Mediator) : Colleague(mediator) {
    override fun send(msg: String) {
        mediator.forward(msg, this)
    }

    override fun receive(msg: String) {
        println("${this::class.java.simpleName}:收到消息--->$msg")
    }
}

Client 客户端测试

/**
 * @create on 2020/6/7 22:41
 * @description 客户端类
 * @author mrdonkey
 */
class Client {
    companion object {
        @JvmStatic
        fun main(args: Array<String>) {
            val mediator = ConcreteMediator()
            val colleagueA = ConcreteColleagueA(mediator)//让通过具体的同事类都安装有wechat这个中介
            val colleagueB = ConcreteColleagueB(mediator)
            mediator.colleagueA = colleagueA//让 wechat 指定这两个同事的存在
            mediator.colleagueB = colleagueB
            println("ConcreteColleagueA:发送消息--->在干嘛呢?")
            colleagueA.send("在干嘛呢?")
            println("ConcreteColleagueB:发送消息--->在发呆呀!")
            colleagueB.send("在发呆呀!")
        }
    }
}

测试结果:

ConcreteColleagueA:发送消息--->在干嘛呢?
ConcreteColleagueB:收到消息--->在干嘛呢?
ConcreteColleagueB:发送消息--->在发呆呀!
ConcreteColleagueA:收到消息--->在发呆呀!

中介者模式的优缺点

中介者模式很容易在系统中应用,也很容易在系统中误用。当系统出现了‘多对多’交互复杂的对象群时,不要急于使用中介者模式,需要先反思你的系统在设计是不是合理。

  • 优点

    • Mediator中介者的出现减少了各个Colleague的耦合,使得可以独立地改变和复用各个Colleague类和Mediator,比如同事A的改变并不会影响同事B,而只是使中介者做出相应改变。
    • 将对象进行集中控制。把对象如何协作进行了抽象,将中介者作为一个独立概念并将其封装在一个对象中 ,中介者处理对象的协作;这样关注的对象就从对象各自本身的行为转移到他们之间的交互上来,也就是站在一个更宏观的角度去看待系统。
  • 缺点

    • 由于 Mediator 进行了集中控制,于是就把对象本身交互的复杂性变成了中介者的复杂性,这就使得中介者会变得比任何一个ConcreteColleague 都复杂。
  • 应用

    • 一般应用于一组定义良好但是以复杂的方式进行通信的场合,以及想定制一个分布在多个类中的行为,而又不想生成太多的子类的场合(每个类中持有这个中介者,他们之间就可以通过一个中介者进行通信,而不必要为每一个通信建造一个类)。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值