《设计模式》中介者模式

news2024/11/25 0:41:34

《设计模式》中介者模式

定义

  • 中介者模式又称为调停者模式,用一个中介对象封装一系列的对象交互,中介者使各对象不需要显式地相互引用,从而使其可以松散耦合,独立地改变它们之间的交互。
  • 属于行为型设计模式。

中介者模式的角色组成

  • Mediator(抽象中介者):定义统一的接口,用于各个同事角色之间的通信。
  • ConcreteMediator(具体中介者):维持对各个同事对象的引用,从具体的同事对象接收消息,向具体同事对象发出命令,通过协调各个同事对象来实现协作行为。
  • Colleague(抽象同事):定义各个同事类公有的方法,并声明了一些抽象方法来供子类实现,同时维持了一个对抽象中介者类的引用,其子类可以通过该引用来与中介者通信。
  • ConcreteColleague(具体同事类):实现了在抽象同事类中声明的抽象方法,每一个同事对象在需要和其他同事对象通信时先与中介者通信,通过中介者来间接完成与其他同事类的通信。

中介者模式的 UML 类图

在这里插入图片描述

🎈情景案例:生活中的租房情景就是中介者模式的体现,房东和租客以及租房中介分别充当了同事和中介者角色:房东将房屋托管给租房中介,而租客从租房中介那边获取房源信息,租房中介充当房东和租客之间的中介者。

抽象中介者 Mediator

public interface Mediator {
    void contact(String message, Person person);
}

抽象同事 Person

public abstract class Person {
    protected String name;
    protected Mediator mediator;

    public Person(String name, Mediator mediator) {
        this.name = name;
        this.mediator = mediator;
    }
}

具体同事房东 LandLord

public class LandLord extends Person {
    public LandLord(String name, Mediator mediator) {
        super(name, mediator);
    }

    public void contact(String message) {
        mediator.contact(message, this);
    }

    public void getMessage(String message) {
        System.out.println("房东" + name + "获取的信息是:" + message);
    }
}

具体同事租客 Tenant

public class Tenant extends Person {
    public Tenant(String name, Mediator mediator) {
        super(name, mediator);
    }

    public void contact(String message) {
        mediator.contact(message, this);
    }

    public void getMessage(String message) {
        System.out.println("租客" + name + "获取的信息是:" + message);
    }
}

具体中介者租房机构 MediatorOrgan

public class MediatorOrgan implements Mediator {
    private LandLord landLord;
    private Tenant tenant;

    public LandLord getLandLord() {
        return landLord;
    }

    public void setLandLord(LandLord landLord) {
        this.landLord = landLord;
    }

    public Tenant getTenant() {
        return tenant;
    }

    public void setTenant(Tenant tenant) {
        this.tenant = tenant;
    }

    @Override
    public void contact(String message, Person person) {
        if (person == landLord) {
            tenant.getMessage(message);
        } else {
            landLord.getMessage(message);
        }
    }
}

调用的客户端 Client

public class Client {
    public static void main(String[] args) {
        MediatorOrgan mediatorOrgan = new MediatorOrgan();

        LandLord landLord = new LandLord("包租婆", mediatorOrgan);
        Tenant tenant = new Tenant("小伙汁", mediatorOrgan);

        mediatorOrgan.setLandLord(landLord);
        mediatorOrgan.setTenant(tenant);

        tenant.contact("我需要租包租婆的房子");
        landLord.contact("小伙汁,我的房子还在可以租给你");
    }
}

中介者模式的优点

  • 将同事对象解耦:中介者的出现减少了各个同事对象的耦合,使得可以独立地改变和复用各个同事和中介者。
  • 简化对象之间的交互:中介者模式使用中介者和同事的一对多交互代替了原来同事之间的多对多交互。一对多关系更容易理解、维护和扩展,将原本难以理解的网状结构转换成相对简单的星形结构。

中介者模式的缺点

  • 在具体中介者类中包含了大量同事之间的交互细节,可能会导致具体中介者类非常复杂,使得系统难以维护。

中介者模式的适用场景

  • 系统中对象之间存在复杂的引用关系,结构混乱难以理解。
  • 想通过一个中间类来封装多个类中的行为,而又不想生成太多的子类。

🎈中介者模式在JDK源码 java.util.Timer 中的应用

Timer 类用于创建定时器任务。它充当了一个中介者的角色,负责协调计时器任务的创建和执行。通过 Timer 类,我们可以创建定时任务,设置任务的执行时间和间隔,并且可以取消已经创建的任务。

定时器Timer类部分源码如下

public class Timer {
	// ...
    public void schedule(TimerTask task, long delay) {
       if (delay < 0)
           throw new IllegalArgumentException("Negative delay.");
       sched(task, System.currentTimeMillis()+delay, 0);
   }
   
   private void sched(TimerTask task, long time, long period) {
        if (time < 0)
            throw new IllegalArgumentException("Illegal execution time.");

        // Constrain value of period sufficiently to prevent numeric
        // overflow while still being effectively infinitely large.
        if (Math.abs(period) > (Long.MAX_VALUE >> 1))
            period >>= 1;

        synchronized(queue) {
            if (!thread.newTasksMayBeScheduled)
                throw new IllegalStateException("Timer already cancelled.");

            synchronized(task.lock) {
                if (task.state != TimerTask.VIRGIN)
                    throw new IllegalStateException(
                        "Task already scheduled or cancelled");
                task.nextExecutionTime = time;
                task.period = period;
                task.state = TimerTask.SCHEDULED;
            }

            queue.add(task);
            if (queue.getMin() == task)
                queue.notify();
        }
    }
    // ...
}

无论什么样的任务都被加入一个队列中按顺序执行,该队列中的所有对象都称为“同事”,同事之间的通信都是通过Timer来协调完成的,Timer承担了中介者的角色。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/701795.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

前端解析后台返回得文件流导出得 pdf为空

封装的方法 download(res, type, filename) {// 创建blob对象&#xff0c;解析流数据const blob new Blob([res.data], {// 如果后端没返回下载文件类型&#xff0c;则需要手动设置&#xff1a;type: application/pdf;chartsetUTF-8 表示下载文档为pdf&#xff0c;如果是word则…

2023上半年软考系统分析师科目一整理-13

2023上半年软考系统分析师科目一整理-13 给定关系模式 R < U &#xff0c;F >&#xff0c; U {A&#xff0c;B&#xff0c;C&#xff0c;D &#xff0c;E} &#xff0c; F {B→A &#xff0c;D→A &#xff0c;A→E &#xff0c;AC→B }&#xff0c;则 R 的候选关键字为…

2023上半年软考系统分析师科目一整理-11

2023上半年软考系统分析师科目一整理-11 给定关系R(A,B,C,D,E) 和关系S(D,E,F,G&#xff09;&#xff0c;对其进行自然连接运算R ▷◁S后其结果集的属性列为( B )。 A. R.A, R.B, R.C, R.D, R.E, S.D, S.E B. R.A, R.B, R.C, R.D, R.E, S.F, S.G C. R.A, R.B, R.C, R.D, R.E,…

爬虫---某翻译响应解密和sign逆向

目标网址接口&#xff1a;aHR0cHM6Ly9kaWN0LnlvdWRhby5jb20vd2VidHJhbnNsYXRl 仅供学习交流使用&#xff0c;非商业用途&#xff0c;如有侵权&#xff0c;请联系删除!!!仅供学习交流使用&#xff0c;非商业用途&#xff0c;如有侵权&#xff0c;请联系删除!!!仅供学习交流使用&…

软件测试技能,JMeter压力测试教程,设置集合点(十七)

一、前言 LoadRunner 中可以设置一个集合点&#xff0c;设置多个虚拟用户等待到一个时间点&#xff0c;到齐后一起发请求达到并发的目的 jmeter 中使用 同步定时器 Synchronizing Timer实现 LoadRunner 中集合点的功能&#xff0c;模拟多用户并发测试&#xff0c;即多个线程在…

K折交叉验证

目的 模型在一套训练集和数据集上表现优秀&#xff0c;不能说明问题&#xff0c;只有在众多不同的训练集和测试集上表现都优秀&#xff0c;模型才具有真正的泛化能力。 通过交叉验证&#xff0c;验证模型的泛化能力&#xff0c;帮助我们认识模型。 常用方法之K折交叉验证 分…

一步一步学OAK之六:通过OAK相机实现特征检测

目录 特征检测Setup 1: 创建文件Setup 2: 安装依赖Setup 3: 导入需要的包Setup 4: 创建pipelineSetup 5: 创建节点创建相机节点创建特征检测节点创建数据交互的节点 Setup 6:设置相关属性设置相机的相关属性设置特征检测器的初始配置 Setup 7: 建立链接关系建立相机和特征跟踪器…

iOS 16 版本适配

1、iOS 16 真机调试时需要在设备的设置 —> 隐私与安全 —> 开发者模式 中打开开发者模式。 2、隐私权限增强&#xff0c;如通过 UIDevice 获取设备名称时&#xff0c;无法获取用户的信息&#xff0c;只能获取设备对应的名称&#xff08;[UIDevice currentDevice].name返…

基于Python所写的影视作品分析设计

点击以下链接获取源码资源&#xff1a; https://download.csdn.net/download/qq_64505944/87964875 《开心麻花影视作品分析》程序使用说明 在PyCharm中运行《开心麻花影视作品分析》即可进入如图1所示的系统主界面。在该界面中&#xff0c;选择要分析的电影名称&#xff0c;然…

android:RadioGroup的使用

一、前言&#xff1a;工作中会遇到勾选不同的类型&#xff0c;获得不同的数据。仅以此笔记记录。 二、上代码&#xff1a; 新建一个Activity public class RadioHorizontalActivity extends AppCompatActivity implements RadioGroup.OnCheckedChangeListener {private Text…

线程并发同步--条件变量--conditional_variable

同步&#xff1a;我的线程完成之后&#xff0c;你在进行下一个线程。可以理解为进货和卖货&#xff0c;即只有进或的线程结束后才可以执行卖货的这个线程。 c中提供了一个工具&#xff1a;conditional_variable。实现有两种方式&#xff0c;一种是condition_variable和conditon…

[java]Redis

关于Redis Redis是一款基于内存的&#xff0c;使用K-V结构存储数据的NoSQL非关系型数据库。 基于内存的&#xff1a;Redis读写数据时&#xff0c;都是在内存中进行读写的&#xff0c;所以&#xff0c;读写效率非常高&#xff01;另外&#xff0c;Redis会自动的将所管理的数据同…

mmdetection自定义数据集训练

目录 1. 源码下载&#xff0c;本文基于v3.0版本 2.选模型训练 2.1 先生成后面用于编译的配置文件 2.2.1 修改coco.py 2.2.2 修改class_names.py 3. 训练配置 4. 训练过程展示 1. 源码下载&#xff0c;本文基于v3.0版本 GitHub - open-mmlab/mmdetection: OpenMMLab Detec…

UART-GD32

UART-GD32 通信的概念 同步通信和异步通信 数据帧格式 波特率 使用步骤 引脚分布

图-深度优先搜索与广度优先搜索

图 在现实生活中&#xff0c;有许多应用场景会包含很多点以及点点之间的连接&#xff0c;而这些应用场景我们都可以用即将要学习的图 这种数据结构去解决 地图 我们生活中经常使用的地图&#xff0c;基本上是由城市以及连接城市的道路组成&#xff0c;如果我们把城市看做是一…

西安石油大学 C++期末考试 重点知识点+题目复习(上)

第一章 “const”关键字的用法 当使用 const 修饰变量、函数参数、成员函数以及指针时&#xff0c;以下是一些代码示例&#xff1a; 声明只读变量&#xff1a; const int MAX_VALUE 100; const float PI 3.14;保护函数参数&#xff1a; void printArray(const int arr[]…

解决vmware虚拟机,克隆修改ip后,xshell连接不上问题

1、查看网卡 ifconfig2、修改网卡配置 vim /etc/sysconfig/network-scripts/ifcfg-ens32 改成与上图一样 修改后 3、重启reboot则解决

STM32F407 串口配置步骤

介绍STM32F407串口配置步骤&#xff0c;完成串口的数据发送与接收、实现中断接收&#xff0c;支持printf重定向。 STM32F407 串口配置说明 STM32F4 的串口资源相当丰富的&#xff0c;功能也相当强劲&#xff0c;STM32F407ZGT6 最多可提供 6 路串口&#xff0c;有分数波特率发…

【Junit 单元测试】

Junit 单元测试 笔记记录 1. Junit介绍2. 使用Junit3. 常用注解4. 断言使用 1. Junit介绍 2. 使用Junit 1.导入依赖 <dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.12</version><scope>tes…

C语言-基础语法学习-4 字符串

目录 字符串C语言字符串及相关函数定义字符数组和字符串的区别sizeof()和strlen()的区别动态开辟字符串野指针常用字符串函数 字符串 C语言字符串及相关函数 在C语言中&#xff0c;字符串是由字符数组表示的一系列字符序列。C语言提供了一些函数来处理字符串&#xff0c;使我…