行为型模式--中介者模式

news2025/1/11 2:28:18

目录

概述

结构

案例实现

优缺点

优点:

缺点:

使用场景

概述

一般来说,同事类之间的关系是比较复杂的,多个同事类之间互相关联时,他们之间的关系会呈现为复 杂的网状结构,这是一种过度耦合的架构,即不利于类的复用,也不稳定。例如在下左图中,有六个同 事类对象,假如对象1发生变化,那么将会有4个对象受到影响。如果对象2发生变化,那么将会有5个 对象受到影响。也就是说,同事类之间直接关联的设计是不好的。

如果引入中介者模式,那么同事类之间的关系将变为星型结构,从下右图中可以看到,任何一个类的变 动,只会影响的类本身,以及中介者,这样就减小了系统的耦合。一个好的设计,必定不会把所有的对 象关系处理逻辑封装在本类中,而是使用一个专门的类来管理那些不属于自己的行为。

 中介者模式又叫调停模式,定义一个中介角色来封装一系列对象之间的交互,使原有对象之间的耦合松散,且可以 独立地改变它们之间的交互。

结构

中介者模式包含以下主要角色:

抽象中介者(Mediator)角色:它是中介者的接口,提供了同事对象注册与转发同事对象信息的 抽象方法。

具体中介者(ConcreteMediator)角色:实现中介者接口,定义一个 List 来管理同事对 象,协调各个同事角色之间的交互关系,因此它依赖于同事角色。

抽象同事类(Colleague)角色:定义同事类的接口,保存中介者对象,提供同事对象交互的抽 象方法,实现所有相互影响的同事类的公共功能。

具体同事类(Concrete Colleague)角色:是抽象同事类的实现者,当需要与其他同事对象交 互时,由中介者对象负责后续的交互。

案例实现

【例】租房

现在租房基本都是通过房屋中介,房主将房屋托管给房屋中介,而租房者从房屋中介获取房屋信息。房 屋中介充当租房者与房屋所有者之间的中介者。

类图如下:

代码如下: 

抽象中介者

public abstract class Mediator {
    //申明一个联络方法
    public abstract void constact(String message,Person person);
}

抽象同事类

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

具体同事类 房屋拥有者

public class HouseOwner extends Person {
    public HouseOwner(String name, Mediator mediator) {
        super(name, mediator);
    }
    //与中介者联系
    public void constact(String message){
        mediator.constact(message, this);
    }
    //获取信息
    public void getMessage(String message){
        System.out.println("房主" + name +"获取到的信息:" + message);
    }
}

具体同事类 承租人

public class Tenant extends Person {
    public Tenant(String name, Mediator mediator) {
        super(name, mediator);
    }
    //与中介者联系
    public void constact(String message){
        mediator.constact(message, this);
    }
    //获取信息
    public void getMessage(String message){
        System.out.println("租房者" + name +"获取到的信息:" + message);
    }
}

具体中介机构

public class MediatorStructure extends Mediator {
    //首先中介结构必须知道所有房主和租房者的信息
    private HouseOwner houseOwner;
    private Tenant tenant;
    public HouseOwner getHouseOwner() {
        return houseOwner;
    }
    public void setHouseOwner(HouseOwner houseOwner) {
        this.houseOwner = houseOwner;
    }
    public Tenant getTenant() {
        return tenant;
    }
    public void setTenant(Tenant tenant) {
        this.tenant = tenant;
    }
    public void constact(String message, Person person) {
        if (person == houseOwner) { //如果是房主,则租房者获得信息
        tenant.getMessage(message);
        } else { //反正则是房主获得信息
        houseOwner.getMessage(message);
        }
    }
}

测试类

public class Client {
    public static void main(String[] args) {
        //一个房主、一个租房者、一个中介机构
        MediatorStructure mediator = new MediatorStructure();
        //房主和租房者只需要知道中介机构即可
        HouseOwner houseOwner = new HouseOwner("张三", mediator);
        Tenant tenant = new Tenant("李四", mediator);
        //中介结构要知道房主和租房者
        mediator.setHouseOwner(houseOwner);
        mediator.setTenant(tenant);
        tenant.constact("需要租三室的房子");
        houseOwner.constact("我这有三室的房子,你需要租吗?");
    }
}

优缺点

优点:

松散耦合 中介者模式通过把多个同事对象之间的交互封装到中介者对象里面,从而使得同事对象之间松散耦 合,基本上可以做到互补依赖。这样一来,同事对象就可以独立地变化和复用,而不再像以前那样 “牵一处而动全身”了。

集中控制交互 多个同事对象的交互,被封装在中介者对象里面集中管理,使得这些交互行为发生变化的时候,只 需要修改中介者对象就可以了,当然如果是已经做好的系统,那么就扩展中介者对象,而各个同事 类不需要做修改。

一对多关联转变为一对一的关联 没有使用中介者模式的时候,同事对象之间的关系通常是一对多的,引入中介者对象以后,中介者 对象和同事对象的关系通常变成双向的一对一,这会让对象的关系更容易理解和实现。

缺点:

当同事类太多时,中介者的职责将很大,它会变得复杂而庞大,以至于系统难以维护。

使用场景

系统中对象之间存在复杂的引用关系,系统结构混乱且难以理解。

当想创建一个运行于多个类之间的对象,又不想生成新的子类时。

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

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

相关文章

深入理解深度学习——BERT派生模型:跨语言模型XLM(Cross-lingual Language Model)

分类目录:《深入理解深度学习》总目录 BERT本应在语义理解上具有绝对优势,但其训练语料均为英语单语,受限于此,早期的BERT只在英语文本理解上有优势。随着全球化进程的加速,跨语言的预训练语言模型也具有非常重要的应用…

seldom之数据驱动

seldom之数据驱动 如果自动化某个功能,测试数据不一样而操作步骤是一样的,那么就可以使用参数化来节省测试代码。 seldom是我在维护一个Web UI自动化测试框,这里跟大家分享seldom参数化的实现。 GitHub:GitHub - SeldomQA/seld…

idea设置项目编码为utf8

设置当前项目的编码为utf8 File -> Settings -> Editor -> File Encoding: 设置新建项目的编码为utf8 File -> New Projects Setup -> Settings for New Projects:

Flutter系列(九)ListView实现新闻列表和正文布局

基础工程: Flutter系列(四)底部导航顶部导航图文列表完整代码_摸金青年v的博客-CSDN博客 相关文章: Flutter系列(七)ListView 图文列表详解_flutter 图文列表_摸金青年v的博客-CSDN博客 一、前言 本文用flutter实现新闻…

注册 Google 邮箱(最新:保姆级教程)

文章目录 1、我们使用浏览器打开谷歌邮箱官网(gmail.google.com),进入谷歌邮箱的登录主页,我们点击左下方的创建账号按钮,选择个人用途 2、在进入的界面我们不要着急填写资料,我们先修改语言,点…

(2023,3D 场景生成器 Infinigen)使用程序化生成的无限逼真世界

Infinite PhotorealisticWorlds using Procedural Generation 公众号:EDPJ 目录 0. 摘要 1. 简介 2. 相关工作 3. 方法 4. 实验 参考 S. 总结 S.1 主要思想 S.2 方法 S.3 场景生成 0. 摘要 我们介绍 Infinigen,一个自然世界逼真 3D 场景的…

Verilog | 除法--试商法

试商法 采用试商法实现除法运算,对于32位的除法,需要至少32个时钟周期才能得到除法结果。下面是试商法的一般过程。 设被除数是m,除数是n,商保存在s中,被除数的位数是k,其计算步骤如下(为了便…

leetcode814. 二叉树剪枝(java)

二叉树剪枝 leetcode814. 二叉树剪枝题目描述DFS 深度优先遍历 二叉树专题 leetcode814. 二叉树剪枝 来源:力扣(LeetCode) 链接:https://leetcode.cn/problems/binary-tree-pruning 题目描述 给你二叉树的根结点 root &#xff0c…

《机器学习公式推导与代码实现》chapter17-kmeans

《机器学习公式推导与代码实现》学习笔记,记录一下自己的学习过程,详细的内容请大家购买作者的书籍查阅。 聚类分析和k均值聚类算法 聚类分析(cluster analysis)是一类经典的无监督学习算法,在给定样本的情况下,聚类分析通过度量…

【半监督:交叉分辨率:解纠缠】

Cross-Resolution Semi-Supervised Adversarial Learning for Pansharpening (用于泛锐化的交叉分辨率半监督对抗学习) 现有的基于深度神经网络(DNN)的方法已经产生了良好的泛锐化图像。然而,监督DNN为基础的泛锐化方…

卷积是什么

参考: 【官方双语】那么……什么是卷积?https://www.bilibili.com/video/BV1Vd4y1e7pj/ [建议看完] x.1 一维卷积 一维卷积,即对于两个向量的卷积,就是将向量翻转后,从前向后滑动,相乘再相加。 x.2 二维卷…

Spring Boot启动原理

Spring Boot的自动配置为我们提供了快捷方便的方式来运行Spring应用,但很多开发者对其内部启动原理还不是很明白。这篇博客旨在解开Spring Boot的神秘面纱,帮助大家理解它的启动原理。 入口类和注解 我们的Spring Boot应用通常从一个主类开始&#xff…

感知机(Perceptron)底层原理

1.感知机(Perceptron)底层原理 声明:笔记来源于《白话机器学习的数学》 感知机是接受多个输入后将每个值与各自权重相乘,最后输出总和的模型。 单层感知机因过于简单,无法应用于实际问题,但它是神经网络和深…

8个很少用,但却很好用的 Python 库!

本文介绍一些我们可能很少听过,但是对于特定问题或者特定任务来说,可能会非常有帮助的 Python 库 技术交流 技术要学会分享、交流,不建议闭门造车。一个人可以走的很快、一堆人可以走的更远。 好的文章离不开粉丝的分享、推荐,文…

黑马程序员前端 Vue3 小兔鲜电商项目——(六)二级分类页

文章目录 二级路由配置模版代码配置路由关系跳转配置 面包屑导航实现封装接口渲染数据 分类基础列表实现准备接口渲染数据 列表筛选实现无限加载实现定制路由 scrollBehavior 二级路由配置 模版代码 创建 src\views\SubCategory\index.vue 文件,添加以下代码&…

云服务器部署企业版openGauss,本地Data Studio远程连接

1.下载安装包 在华为云上租一台服务器,操作系统选:openEuler 20.03 64bit (64-bit) 获取openGauss Server安装包,企业版:软件包链接 使用xshell连接服务器,准备软硬件安装环境。准备软硬件安装环境 教程 下载Data …

javaee 过滤器加cookie实现自动登录

思路 如上图,如果勾选了自动登录,在登录时,就将用户名和密码存储到cookie中,当下次访问首页时,过滤器先拦截请求,获取下cookie中的账号密码,然后如果cookie中的账号密码有效就将登录信息存储到…

Paddle FastDeploy 执行Cmake 时错误处理方法

1.Paddle FastDeploy 在cmake 时的命令执行报错处理 命令是参考官网的,如下: git clone https://github.com/PaddlePaddle/FastDeploy.git cd FastDeploy mkdir build && cd build cmake .. -G "Visual Studio 16 2019" -A x64 \-DENABLE_ORT_BA…

【MyBatis-Plus】入门案例与简介

1,MyBatisPlus入门案例与简介 1. 入门案例 MybatisPlus(简称MP)是基于MyBatis框架基础上开发的增强型工具,旨在简化开发、提供效率。 开发方式 基于MyBatis使用MyBatisPlus基于Spring使用MyBatisPlus基于SpringBoot使用MyBatisPlus SpringBoot刚刚我…

工资管理系统(学校期末作业)

一、 题目要求 1、需求分析 工资信息存放在文件中,提供文件的输入、输出等操作;要浏览,提供显示、排序操作;查询功能要求实现查找操作;提供键盘式选择菜单以实现功能选择。 2、总体设计 系统可分为信息输入、信息添…