Java设计模式之中介者模式

 更新时间:2022年10月11日 09:00:45   作者:tianClassmate  
这篇文章介绍了Java设计模式之中介者模式,文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

在我们实际业务中,可能存在多个类之间相互调用,形成了一个复杂的网状结构。这时候就需要有一种模式去“捋顺”他们之间的关系,引出一个中间者让类之间不再相互调用,该模式就是我们今天的主人公——中介者模式。

一、概念理解

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

大白话解释就是,引入一个“中介”,用于协调各个对象的关系,各个对象之间不用那么直白的直接调,对象只需要调用中介的方法,中介内部进行逻辑判断,由中介去调用各个对象的方法。

概念基本清楚以后接着看中介者模式包含的角色都有哪些:

中介者角色、各个对象角色是必须的,在面向接口编程原则下,中介者和对象应该抽离出来接口,于是在中介者模式的结构中就包括四种角色(各个对象角色称为同事):

1.中介者(Mediator):中介者是一个接口,该接口定义了用于同事(Colleague)对象之间进行通信的方法;

2.具体中介者(ConcreteMediator):具体中介者是实现中介者接口的类。具体中介者需要包含所有具体同事(ConcreteColleague)的引用,并通过实现中介者接口中的方法来满足具体同事之间的通信要求;

3.同事(Colleague):一个接口,规定了具体同事需要实现的方法;

4.具体同事(ConcreteColleague):实现了同事接口的类。具体同事需要包含具体中介者的引用,一个具体同事需要和其他具体同事交互时,只需将自己的请求通知给它所包含的具体中介者的引用。

如果在一个业务场景中,一个公司有很多同事,同事1 管理的有自己的数据,有时候也会调用同事2的数据。

在中介者模式下,同事1和同事2 之间不再相互调用,由中介者统一调用,同事类中要持有中介者对象,中介者方法中要有判断属于哪个角色的方法。

基于四个角色,实现初试的demo。

读者可以拉取完整代码到本地进行学习,实现代码均测试通过后上传到码云

本地源码下载

二、案例实现

抽象同事类:

抽象同事中要持有中介者的引用

/**
 * 抽象同事类
 * @author tcy
 * @Date 14-09-2022
 */
public abstract class Colleague {

    //抽象中介者引用
    protected Mediator mediator;

    public Colleague(Mediator mediator)
    {
        this.mediator = mediator;
    }
    //数据更新方法
    public abstract void update();
    //数据更改方法
    public abstract void changed();
}

具体同事类1、2:

具体同事类除了有自己的业务逻辑之外,应该还有额外调用中介者的方法

/**
 * 具体同事2
 * @author tcy
 * @Date 14-09-2022
 */

public class ConcreteColleague2 extends Colleague {

    public ConcreteColleague2(Mediator mediator)
    {
        super(mediator);
    }

    //自己的方法
    @Override
    public void update()
    {
        System.out.println("更新同事类2");
    }

    //调用同事的方法
    @Override
    public void changed()
    {
        System.out.println("同事类2数据更改");
        mediator.operation(this);
    }

}

/**
 * 具体同事1
 * @author tcy
 * @Date 14-09-2022
 */
public class ConcreteColleague1 extends Colleague{

    public ConcreteColleague1(Mediator mediator)
    {
        super(mediator);
    }

    @Override
    public void update()
    {
        System.out.println("更新同事类1");
    }

    @Override
    public void changed()
    {
        System.out.println("同事类1数据更改");
        mediator.operation(this);
    }


}

抽象中介者:

抽象中介者应该是持有所有同事对象,并且应该有一个方法去调用别的同事

/**
 * 抽象中介者
 */
public abstract class Mediator {

    protected ArrayList<Colleague> colleagues = new ArrayList<>();

    public void add(Colleague colleague)
    {
        colleagues.add(colleague);
    }

    public abstract void operation(Colleague colleague);

}

具体中介者:

具体中介者实现抽象中介者的方法,根据条件调用不同的同事

/**
 * 具体中介者
 * @author tcy
 * @Date 14-09-2022
 */
public class ConcreteMediator extends Mediator {

    @Override
    public void operation(Colleague colleague)
    {
        if(colleague instanceof ConcreteColleague1)
            colleagues.get(1).update();
        else if(colleague instanceof ConcreteColleague2)
            colleagues.get(0).update();
    }

}

三、中介者模式源码中的应用

中介者模式的典型应用就是Jdk中的Timer 类。

我们知道Timer 类的主要作用是用于定时任务,定时任务之间会存在通信问题,如果众多的定时任务都相互通信,那对于系统对象间的引用来说就是一灾难,引出中介者模式就是理所应当的了。

当有新的任务加入到队列中,均把该任务当做同事,各个任务之间的通信都是由Timer 类来完成,Timer 类就相当于中介者的角色。

我们知道,Timer 类实现定时任务的主要方法就是schedule(),schedule()有一堆的重载方法。

我们点开任意的schedule方法。

public void schedule(TimerTask task, Date firstTime, long period) {
    if (period <= 0)
        throw new IllegalArgumentException("Non-positive period.");
    sched(task, firstTime.getTime(), -period);
}

均调用了sched()私有方法。

我们重点看红线标记的代码块,将任务放入一个 队列中,这个队列和我们例子中的Arrlist是一个作用。

private final TaskQueue queue = new TaskQueue();

判断以后,调用Object的notify()方法,进行线程间的通信。

试想一下,如果没有这个中介,每个定时任务都手动的调用notify()方法,该有多么痛苦。

四、总结

网上讲解设计模式的文章很多,能把中介模式讲清楚很简单,但能说明白何时使用合适的设计模式却是难上加难。在前三章设计模式的基础之上,第四章总结看完,希望读者能对正确使用设计模式有一个清晰的轮廓。

很多网上的博客都说要职责清晰才可使用中介者模式,如果类的职责是混乱的,那中介者的逻辑写起来就很难受。还有多个对象间耦合严重,类图之间出现了网状结构,这时候就可以考虑中介者模式了,如果仅仅是为了使用中介者模式而使用,那就得不偿失了。

中介者的优点突出,中介者模式的出现会让网状结构,有序的转化为星状结构。能有序降低类的复杂度,将多对多的关系转化为一对多,降低了类之间的耦合。

缺点也很明显,会增加类的个数,同事类越多,中介者的逻辑也就越复杂。

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对脚本之家的支持。如果你想了解更多相关内容请查看下面相关链接

相关文章

  • java使用common-httpclient包实现post请求方法示例

    java使用common-httpclient包实现post请求方法示例

    这篇文章主要给大家介绍了关于java使用common-httpclient包实现post请求的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2018-08-08
  • java实现Api接口加密通信方式

    java实现Api接口加密通信方式

    这篇文章主要介绍了java实现Api接口加密通信方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-06-06
  • Java面向对象之多态

    Java面向对象之多态

    这篇文章主要介绍了Java面向对象之多态,文章以什么是多态、多态的实现条件、多态的访问特点、多态的优点和缺点的相关资料展开文章内容,需要的小伙伴可以参考一下
    2021-10-10
  • Java 批量获取地址间距离工具(支持中转站)

    Java 批量获取地址间距离工具(支持中转站)

    本文主要介绍了Java批量获取地址间距离,获取两个地址间距离,实现方式比较多,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-07-07
  • Java 实战项目锤炼之IT设备固定资产管理系统的实现流程

    Java 实战项目锤炼之IT设备固定资产管理系统的实现流程

    读万卷书不如行万里路,只学书上的理论是远远不够的,只有在实战中才能获得能力的提升,本篇文章手把手带你用Java+SSM+jsp+mysql+maven实现一个IT设备固定资产管理系统,大家可以在过程中查缺补漏,提升水平
    2021-11-11
  • java ThreadGroup的作用及方法详解

    java ThreadGroup的作用及方法详解

    这篇文章主要介绍了java ThreadGroup的作用及方法,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-10-10
  • 在 Java 中将Object 转换为 Int的四种方法

    在 Java 中将Object 转换为 Int的四种方法

    这篇文章主要介绍了在Java中如何将 Object 转换为Int,本文研究了在 Java中将Object转换为int的四种不同方法,结合示例代码给大家介绍的非常详细,需要的朋友可以参考下
    2023-05-05
  • SpringCloud重试机制配置详解

    SpringCloud重试机制配置详解

    本篇文章主要介绍了SpringCloud重试机制配置详解,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-04-04
  • Spring Boot快速实现 IP地址解析的示例详解

    Spring Boot快速实现 IP地址解析的示例详解

    这篇文章主要介绍了Spring Boot快速实现IP地址解析,本文通过示例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-08-08
  • SpringSecurity表单配置之登录成功及页面跳转原理解析

    SpringSecurity表单配置之登录成功及页面跳转原理解析

    这篇文章主要介绍了SpringSecurity表单配置之登录成功及页面跳转原理解析,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧
    2023-12-12

最新评论