java如何通过中间层来解耦

588 阅读5分钟

530631629042694_.pic.jpg

这是我参与8月更文挑战的第15天,活动详情查看:8月更文挑战

今天我们一起来学习下代码实现简单、也容易理解的一种模式----中介者模式。多唠叨几句,我本月将会对java的设计模式精讲,欢迎点击头像,关注我的专栏,我会持续更新,加油!

设计模式系列:

设计模式之单例模式

设计模式之工厂模式

设计模式之建造者模式

设计模式之代理模式

设计模式之访问者模式

设计模式之适配器模式

设计模式之命令者模式

java状态模式 | 随时随地监控状态改变

java观察者模式 | 如何通知事物的变化

java备忘录模式 | 如何记录历史信息

java迭代器模式模式 | 如何对各个元素进行访问

java享元模式 | 如何共享对象

java解释器模式 | 自定义规则实现逻辑

java桥接模式 | 抽象与不同实现的绑定

java桥接模式 | 抽象与不同实现的绑定

持续更新中......

话不多说,进入正题

中介者模式

顾名思义,就是“房产中介”,“买车销售顾问”。是的,他们是作为中间人,来解决一些问题,用户无法直接访问最底层。可以风趣的称之为,流量低挡着,流量分发者。我个人理解,也可以用nginx的思想来理解该模式。nginx的一个重要作用,就是一个中间者,将流量分发给不同的服务。解耦流量并发问题。

官方定义:中介者对象封装了一组对象之间的交互,这组对象会将它们的交互委托给中介者对象,而不是直接交互。

注意:这个定义非常简单和明确,中介者对象就是用于处理对象与对象之间的直接交互,封装了多个对象之间的交互细节。

看到这里就大概明白很多了 我们接着往下看一个图

image.png

从该图中,我们能看出中介者模式包含了四个关键角色。

  • 抽象中介者(Mediator):定义中介者需要执行的方法操作。(接口或者抽象类)

  • 具体中介者(MediatorImpl):实现抽象中介者定义的方法操作,同时可以包含更多逻辑。

  • 抽象组件类(Component):定义组件需要执行的方法操作。

  • 具体组件类(ComponentA、ComponentB):继承自抽象组件类,实现具体的组件业务逻辑。

我们可以看出,哪里是解藕的:在组件与组件之间加入一个中间对象来进行间接通信。这一层来达到解藕的目的。

下面我们通过具体场景代码来实现下:

代码展示

我们先来模式一个场景,我们都知道一个班级里面,老师要下发什么任务,比如布置了学习任务,打扫卫生任务,,,,,,如果要每次找学习委员和卫生委员太过麻烦。这时候出现了班长这个“中介者”角色。班长来协调各项任务

接下来我们用代码实现下:

定义一个中介者接口以及相关方法

//中介者接口类
public interface Mediator {
    //将学习委员、卫生委员等各类委员注册进来
    void register(String lname,ClassLeader c);
    
    //班长根据委员名字获得通知请求
    void command(String lname);
}

定义一个学委的接口以及相关方法

//班干部接口
public interface ClassLeader {
    //本职工作
    void job();
    
    //向班长提出请求
    void sendRequest();
}

具体委员角色

 //学习委员
 public class StudyLeader implements ClassLeader {
 
     //持有对班长大人的引用
     private Mediator media;
 
     public StudyLeader(Mediator media) {
         super();
         this.media = media;
         media.register("StudyLeader", this);
     }
 
     @Override
     public void job() {
         System.out.println("学习委员->最近小张的学习成绩有所下降,需要我的帮助!");
     }

    @Override
    public void sendRequest() {
         System.out.println("学习委员->小张是不是有什么精神负担,班长大人去叫心理委员去看看什么情况吧!");
         media.command("phycologic");
    }
}
 //心理委员
public class PhychologicalLeader implements ClassLeader {
    //持有对班长大人的引用
    private Mediator media;
    
    public PhychologicalLeader(Mediator media) {
        super();
        this.media = media;
        media.register("phycologic", this);
    }

    @Override
    public void job() {
        System.out.println("心理委员->小张最近心情好像不太好,需要我的帮助!");
    }

    @Override
    public void sendRequest() {
        System.out.println("心理委员->解决小张的心理问题!");
         //media.command("LifeLeader");
     }
}
//班长
public class ClassMonitor implements Mediator {
   //利用map集合存放学委的相关属性
    private Map<String,ClassLeader> map=new HashMap<String,ClassLeader>();
   
    //将对应名称的学委对象进行注册
    @Override
    public void register(String lname, ClassLeader c) {
       map.put(lname, c);
    }
    //班长大人获取来自指定学委的请求通知
    @Override
    public void command(String lname) {
        map.get(lname).job();
    }
}
//调用
public class Client {

    public static void main(String[] args) {
        Mediator m=new ClassMonitor();
        ClassLeader study=new StudyLeader(m);
        ClassLeader phycho=new PhychologicalLeader(m);
        //当前委员发送请求给班长然后通过班长与其他委员通信
        System.out.println("------学习委员->班长->心理委员");
        study.sendRequest();
        System.out.println("------心理委员->");
        phycho.sendRequest();        
    }
}

OK 代码就到这里。我们痛过一段简单的代码可以发现两点,

  • 中介者模式的关键点就在于在组件与组件之间加入一个中间对象来进行间接通信。虽然多了“一层”会更烦琐些,但是这样就可以在中介者里进行其他的一些操作

  • 中介者在使用时需要知道对象之间的交互关系,然后通过封装这些交互关系的变化让对象在使用中介者时变得更简单。

总结

我们试着想下为什么要用中介者模式

第一个,解决对象之间直接耦合的问题

第二个,在结构上作为中转,解耦两个服务或系统之间的直接耦合关系

第三个,为了更便捷地统一协同对象之间的通信

image.png

当然缺点还是有的

1、中介者会庞大,变得复杂难以维护

2、中介者需要知道所有对象交互的逻辑

弦外之音

感谢你的阅读,如果你感觉学到了东西,麻烦您点赞,关注。

我已经将本章收录在专题里,点击下方专题,关注专栏,我会每天发表干货,本月我会持续输入设计模式。

加油! 我们下期再见!