设计模式之中介者模式

Posted ProChick

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了设计模式之中介者模式相关的知识,希望对你有一定的参考价值。

1.简要概述

  • 中介者模式是实现相关对象之间复杂沟通的控制方式,用一个中介对象封装一系列的对象交互,使得各个对象之间不再需要显式的互相调用。
  • 中介者模式是用来降低多个对象和类之间的通信复杂性,通常处理不同类之间的通信,并支持松耦合,使代码易于维护。
  • 中介者模式的本质就是将多个有关联的对象进行解耦,让每个对象都持有一个相同的中介者对象的引用,然后通过这个引用完成它们之间的交互。

2.模式结构

👉通常由一个中介者抽象类( 负责定义用于对每一个同事对象进行通信的方法接口 ),多个具体的中介者类( 负责维护所有的同事对象,并实现它们之间进行互相通信的方法逻辑 ),一个同事抽象类( 负责定义同事对象之间的公共方法接口 ),多个具体的同事类( 依赖于中介者对象,负责实现向中介者发送消息、接收来自于中介者消息的逻辑 ),一个客户类( 负责对中介者进行调用,完成同事对象之间的互相通信)共同组成。

3.实现代码

举例 💡 :假设现在公司有三个部门,分别是财务部、市场部、研发部,那么市场部每接到一个项目就需要通知研发部进行开发,每到领薪资时市场部和研发部就需要向财务部要账等等。我们看到这些业务的执行都需要三个部门之间打交道,如果部门过多的话,那么它们之间的交互关系将会更加复杂,所以我们可以找一个经理来协调它们之间的通信,那么这里我们就可以采用中介者模式的手段解决此问题。

中介者抽象类

public abstract class Mediator {
    
    abstract void registerDepartment(String name, Department department);
    
    abstract void getMessage(String msg);
}

经理(具体的中介者类)

public class LeaderMediator extends Mediator {
    private Map<String, Department> departments;
    
    public LeaderMediator(){
        this.departments = new HashMap<>();
    }
    
    @Override
    public void registerDepartment(String name, Department department){
        departments.put(name, department);
    }
    
    @Override
    public void sendMessage(String msg, String departmentName){
        switch (departmentName) {
            case "finance":
                departments.get(departmentName).do("向财务部发送通知:" + msg);
                break;
            case "development":
                departments.get(departmentName).do("向开发部发送通知" + msg);
                break;
            case "market":
                departments.get(departmentName).do("向市场部发送通知" + msg);
                break;
        }
    }
}

部门抽象类(同事抽象类)

public abstract class Department {
    protected Mediator mediator;
    
    public Department(Mediator mediator){
        this.mediator = mediator;
    }
    
    public abstract void sendMessage(String message, String departmentName);
    
    public abstract void do(String task);
}

财务部(具体同事类)

public class Finance extends Department {

    public Finance(String name, Mediator mediator){
    	super(mediator);
        mediator.registerDepartment(name, this);
    }
    
    @Override
    public void sendMessage(String message, String departmentName) {
        mediator.sendMessage(message, departmentName);
    }

    @Override
    public void do(String task) {
        System.out.println(task);
    }
}

市场部(具体同事类)

public class Market extends Department {

    public Finance(String name, Mediator mediator){
    	super(mediator);
        mediator.registerDepartment(name, this);
    }
    
    @Override
    public void sendMessage(String message, String departmentName) {
        mediator.sendMessage(message, departmentName);
    }

    @Override
    public void do(String task) {
        System.out.println(task);
    }
}

研发部(具体同事类)

public class Development extends Department {

    public Finance(String name, Mediator mediator){
    	super(mediator);
        mediator.registerDepartment(name, this);
    }
    
    @Override
    public void sendMessage(String message, String departmentName) {
        mediator.sendMessage(message, departmentName);
    }

    @Override
    public void do(String task) {
        System.out.println(task);
    }
}

客户类

// 测试客户端
public class MediatorClient{
    public static void main(String[] args) {
        // 创建中介者
        Mediator mediator = new LeaderMediator();
        
        // 创建财务部
        Department financeDepartment = new Finance("finance", mediator);
        // 创建市场部
        Department marketDepartment = new Market("market", mediator);
        // 创建研发部
        Department developmentDepartment = new Development("development", mediator);
        
        // 市场部通知研发部
        marketDepartment.sendMessage("进行开发工作", "development");
        
        // 研发部通知财务部
        developmentDepartment.sendMessage("该发工资了", "finance");
    }
}

4.优点好处

  • 中介者模式降低了类与类之间的复杂度,将对象间的一对多关联转变为一对一的关联,提高系统的灵活性,使得系统易于维护和扩展。
  • 中介者模式减少了对象之间的依赖,降低了耦合,符合迪米特法则。

5.缺点弊端

  • 中介者模式中,中介者角色承担了所有关联对象的枢纽,所以一旦中介者出现了问题,将导致所有的对象之间不可完成相互通信。
  • 由于中介者需要维护管理所有相关联的同事对象,所以内部逻辑会很复杂,使得系统难以维护。

6.应用场景

  • 当系统中对象之间存在比较复杂的引用关系,导致它们之间的依赖关系结构混乱,而且难以复用的时候,就可以使用中介者模式进行解耦。
  • 当一个系统中对象之间的联系呈现为网状结构,也就是对象之间存在大量的多对多关系的时候,就可以使用中介者模式。
  • 当想通过一个中间类来封装多个类中的交互行为,而又不想生成太多的子类的时候,就可以使用中介者模式。

7.应用示例

JDK源码中的Timer类的定时任务调用

  1. JDK中的Timer类就相当于中介者类,里面维护了一个TaskQueue的任务队列,那么队列里面的一个个任务就可以看作是要协调通信的一个个同事对象。

  2. 在Timer类中定义了schedule方法,用于通知执行某一个任务,完成协调工作。

  3. 这里的TimerTask抽象类就相当于同事抽象类,里面定义了一个run方法用于执行特定的任务操作。

  4. 这里的AutoShutdownTask类继承了TimerTask抽象类,作为一个具体的同时类,实现了执行任务操作的run方法。

  5. 所以从上述的过程可以看出,所有的任务都会通过Timer这个中介者完成任务的调用执行操作,而每个任务之间是不会进行相互关联的,所以符合中介者模式的设计。

以上是关于设计模式之中介者模式的主要内容,如果未能解决你的问题,请参考以下文章

设计模式之中介模式与解释器模式详解和应用

设计模式之中介模式

java设计模式之中介者模式

折腾Java设计模式之中介者模式

设计模式之中介者模式20170731

设计模式——行为型模式之中介者模式