Java设计模式之行为型-中介者模式(UML类图+案例分析)

news2024/11/26 7:40:00

目录

一、基础概念

二、UML类图

三、角色设计

四、案例分析

五、总结


一、基础概念

中介者模式的核心思想是引入一个中介者对象,来封装和管理对象之间的交互关系。

对象之间不再直接交互,而是通过中介者间接交互。这样可以减少对象之间的依赖,实现解耦。中介者就像是对象之间的调停者,协助对象間的交流与相互操作。

总体上,中介者模式可以使原本相互耦合的对象变成松散耦合,提高了灵活性和可维护性。中介者对象承担了对象間交互的责任,每个对象只需关注自身的行为和逻辑,不再与其他对象直接交互。 

二、UML类图

三、角色设计

角色描述
抽象中介者定义接口用于与各同事对象通信
抽象同事相关对象之间通信的对象,它们之间的通信必须通过中介者对象进行
具体中介者实现中介者的接口,它需要知道所有同事类,并接受同事对象的通知,然后调用同事对象的方法
具体同事类实现同事的接口,每一个同事类只知道自己的行为,而不了解其他同事类的情况,但是它们可以通过中介者联系其他对象

四、案例分析

下面通过代码实现了一个使用中介者模式的聊天程序的示例:

定义抽象聊天中介者角色:

public interface ChatMediator {

  public void sendMessage(String msg, User user);
  
  public void registerUser(User user);

}

 实现具体的聊天中介者:

import java.util.ArrayList;
import java.util.List;

public class ChatMediatorImpl implements ChatMediator {

  private List<User> users = new ArrayList<>();

  @Override
  public void sendMessage(String msg, User user) {
    for(User u : this.users) {
      if(u != user) {
        u.receiveMessage(msg); 
      }
    }
  }

  @Override
  public void registerUser(User user) {
    this.users.add(user);
  }

}

定义抽象用户:

public abstract class User {

  private String name;
  
  private ChatMediator mediator;
  
  public User(String name, ChatMediator mediator) {
    this.name = name;
    this.mediator = mediator;
  }

  public ChatMediator getChatMediator() {
    return mediator;
  }

  public String getName() {
    return name;
  }

  public abstract void sendMessage(String msg);

  public abstract void receiveMessage(String msg);


}

分别实现具体的用户,Mike和Jack: 

public class Mike extends User{

    public Mike(String name, ChatMediator mediator) {
        super(name, mediator);
    }

    @Override
    public void sendMessage(String msg) {
        this.getChatMediator().sendMessage(msg, this);
    }

    @Override
    public void receiveMessage(String msg) {
        System.out.println(this.getName() + "收到信息: " + msg);
    }
}

public class Jack extends User{

    public Jack(String name, ChatMediator mediator) {
        super(name, mediator);
    }

    @Override
    public void sendMessage(String msg) {
        this.getChatMediator().sendMessage(msg, this);
    }

    @Override
    public void receiveMessage(String msg) {
        System.out.println(this.getName() + "收到信息: " + msg);
    }
}

客户端:

public class Client {

    public static void main(String[] args) {
        // 初始化中介者
        ChatMediator mediator = new ChatMediatorImpl();

        // 初始化用户
        User user1 = new Mike("Mike", mediator);
        User user2 = new Jack("Jack", mediator);

        // 注册用户
        mediator.registerUser(user1);
        mediator.registerUser(user2);

        // 用户互相通信
        user1.sendMessage("你好,我是Mike!");
        user2.sendMessage("你好,我是Jack!");
    }
}

运行结果如下:

整体实现如下: 

1ChatMediator接口定义了中介者的角色,包含sendMessageregisterUser两个方法。

2ChatMediatorImpl实现了ChatMediator接口,作为具体的中介者实现。它维护了一个用户列表users,并在sendMessage方法中遍历该列表,将消息转发给除发送用户外的其他用户。

3User类定义了用户的抽象类,持有中介者对象的引用。它有两个抽象方法sendMessagereceiveMessage

4JackMike类继承自User类,实现了sendMessagereceiveMessage方法,通过中介者的引用调用其方法来发送和接收消息。

5Client类充当客户端角色,创建中介者和用户对象,建立他们之间的关系,并触发他们之间的交互 - 互相发送消息。

总体上,这段代码通过中介者模式实现了用户对象之间的解耦。用户对象不再直接交互,而是通过中介者转发消息。这使得用户对象可以独立变化,新增用户很方便,只需要注册到中介者即可。也遵循了单一职责原则,用户对象只负责自身消息发送接收,中介者负责协调转发。 

五、总结

优点:

1、降低了对象之间的耦合度。对象之间不再直接交互,它们仅需要保持与中介者的依赖关系即可。

2、提高了系统的灵活性。可以独立地改变对象之间的交互。只需要调整中介者的逻辑,不需要修改对象本身。

3、简化了对象。对象本身只需要关注自身的行为逻辑,不需要处理与其他对象的交互关系。

4、提高了复用性。可以复用中介者类,而不需要了解其内部工作机制。

缺点:

1、中介者会变得过于复杂。中介者需要处理所有对象之间的交互,这使得它经常成为一个庞大的类。

2、依赖中介者。整个系统依赖于中介者,一旦中介者发生问题,会影响到所有交互对象。

应用场景:

1、系统中对象间存在复杂的引用关系,产生的相互依赖关系结构混乱且难以理解。

2、一个对象由于引用其他很多对象,导致难以复用该对象。 -想通过一个中间类消除对象之间的紧耦合关系。

符合的设计原则:

1、单一职责原则(Single Responsibility Principle)

中介者专注于对象之间的交互,对象专注于自身的行为和状态,符合单一职责原则。

2、开闭原则(Open Closed Principle)

可以在不修改对象自身的情况下,通过扩展中介者来改变对象交互,符合开闭原则。

3、依赖倒置原则(Dependency Inversion Principle)

对象依赖于中介者接口,而不是具体的中介者类,符合依赖倒置原则。

4、接口隔离原则(Interface Segregation Principle)

中介者模式通过接口定义对象对外交互,符合接口隔离原则,防止污染不需要的接口。

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

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

相关文章

浏览器调试技巧

浏览器调试技巧 文章将介绍几个 devtools 技巧。 缩放devtool ui 可能对于某些开发来说devtools 中的文本和按钮太小&#xff0c;使用起来不舒服。而浏览器也提供了可以缩放 devtools UI的方法。 devtools 的用户界面是使用 HTML、CSS 和 JavaScript 构建的&#xff0c;这意…

中国地图数据可视化制作,python的pyecharts模块读取excel中国着色地图可视化

数据格式如下&#xff1a; import pandas as pd from pyecharts import options as opts from pyecharts.charts import Map from pyecharts.globals import ChartType# 读取Excel数据 data pd.read_excel(C:\\Users\\Administrator\\Desktop\\国内数据.xlsx)# 创建地图实例 m…

大学英语四六级考点听力案例-内蒙古民族大学外国语学院四六级考试听力电台

大学英语四六级考点听力案例-内蒙古民族大学外国语学院四六级考试听力电台 北京海特伟业科技有限公司发布于2023年7月13日 文/任洪卓 一、大学英语四六级考点听力广播系统用户需求 内蒙古民族大学位于内蒙古东部通辽市&#xff0c;是一所综合型民族大学&#xff0c;为内蒙古自…

电子水尺——实时监测、高精度测量

法国作家雨果说过&#xff1a;一个城市的良心是下水道。当洪水四溢时&#xff0c;城市的下水道让滔滔之水悄然排淌&#xff0c;城市回归安详。 往期&#xff0c;水位监测总是“被动”执行&#xff0c;这样的做法不仅效率低下&#xff0c;还难以做到及时调度和合理应对。 山东…

2023.7.13-输入一个整数n,输出从1开始累加到n的求和

从1累加到n的计算公式为S(1n)n/2。 程序&#xff1a; #define _CRT_SECURE_NO_WARNINGS 1 #include<stdio.h> int main() {int a1;int i 0;int sum 0;printf("整数n的值:");scanf("%d",&a);for (i 0; i < a; i){sum i;}printf("从…

opencv 05 彩色RGB像素值操作

opencv 05 彩色RGB像素值操作 RGB 模式的彩色图像在读入 OpenCV 内进行处理时&#xff0c;会按照行方向依次读取该 RGB 图像的 B 通道、G 通道、R 通道的像素点&#xff0c;并将像素点以行为单位存储在 ndarray 的列中。例如&#xff0c; 有一幅大小为 R 行C 列的原始 RGB 图像…

用户案例 | Apache DolphinScheduler 离线调度在自如多业务场景下的应用与实践

用户案例 | 自如 随着自如业务的快速发展&#xff0c;不断增长的调度任务和历史逾万的存量任务对平台稳定性提出了更高的要求。同时&#xff0c;众多非专业开发人员也需要一种更为“亲民”的调度平台使用体验。 如何满足这些日渐凸显的需求对自如大数据平台的开发团队来说&am…

重复值--Pandas

1. 删除重复行&#xff1a;drop_duplicate() 1.1 函数功能 返回去除重复行的DataFrame&#xff0c;不考虑索引。 1.2 函数语法 DataFrame.drop_duplicates(subsetNone, *, keepfirst, inplaceFalse, ignore_indexFalse)1.3 函数参数 参数含义subset列标签或列标签组成的列…

操作系统第四篇

C语言 第四章 C语言4.1 gcc简介4.2 C语言基础4.3 GNU Binutils 简介4.4 8086 汇编与 C 语言混合编程4.4.1 混合编程的几个问题4.4.2 混合编程的一个实例 第四章 C语言 前面章节用 x86 汇编语言写了引导记录 mbr.bin&#xff0c;并让 BIOS 引导到内存 0x07c00 处执行成功。然后用…

Git 工具出现克隆库失败详解

Git 工具出现克隆库失败详解 现象 错误字符串&#xff1a;git unable to access xxx: Encountered end of 原因 总体来说出现这个原因通常是因为网络连接的问题。具体的有以下几个方面 远程仓库不存在&#xff1a;检查所指定的远程仓库是否存在&#xff0c;确保仓库名称、U…

嵌套虚拟机-监控嵌套虚拟机-libvmi-volatility

接上回&#xff1a; libvmi监控-使用examples cd ~ git clone https://github.com/libvmi/libvmi.git cd libvmi mkdir build cd build # 注意&#xff0c;由于我们是vmi的虚拟机&#xff0c;所以cmake编译时需要加上该编译选项&#xff08;参考libvmi github上的readme&…

积分图像、图像分割、Harris角点检测

目录 1、积分图像 2、图像分割--漫水填充 3、图像分割--分水岭法 4、Harris角点检测 1、积分图像 //积分图像 int test1() {//创建一个1616全为1的矩阵,因为2561616Mat img Mat::ones(16, 16, CV_32FC1);//在图像中加入随机噪声RNG rng(10086);for (int y 0; y < img.r…

路径规划算法:基于法医调查优化的路径规划算法- 附代码

路径规划算法&#xff1a;基于法医调查优化的路径规划算法- 附代码 文章目录 路径规划算法&#xff1a;基于法医调查优化的路径规划算法- 附代码1.算法原理1.1 环境设定1.2 约束条件1.3 适应度函数 2.算法结果3.MATLAB代码4.参考文献 摘要&#xff1a;本文主要介绍利用智能优化…

听GPT 讲K8s源代码--pkg(二)

在 Kubernetes&#xff08;K8s&#xff09;项目中&#xff0c;pkg/controller 目录是用于存放控制器&#xff08;Controller&#xff09;相关的代码的目录。控制器是 Kubernetes 的核心组件之一&#xff0c;用于管理和控制集群中的资源对象的状态和行为。 pkg/controller 目录的…

RTCP/SRTCP介绍

RFC 4585 - Extended RTP Profile for Real-time Transport Control Protocol (RTCP)-Based Feedback (RTP/AVPF) RFC 5124 - Extended Secure RTP Profile for Real-time Transport Control Protocol (RTCP)-Based Feedback (RTP/SAVPF) 译文&#xff1a; http://www.gpssoft…

[SAM]A Comprehensive Survey on Segment Anything Model for Vision and Beyond

A Comprehensive Survey on Segment Anything Model for Vision and Beyond Abstract 本文是SAM的第一篇综述 讲述了SAM的发展历史、进展、在不同任务、不同数据类型下的应用 首先介绍专有名词和背景知识 其次介绍SAM再图像处理等应用中的优点和局限 以及SAM未来展望 git链接…

C# Linq 详解一

目录 一、概述 二、Where 三、Select 四、GroupBy 五、First / FirstOrDefault 六、Last / LastOrDefault​​​​​​​ 一、概述 语言集成查询 (LINQ) 是一系列直接将查询功能集成到 C# 语言的技术统称。 数据查询历来都表示为简单的字符串&#xff0c;没有编译时类型…

Exceptional C++读书笔记——泛型程序设计与C++标准库

更新中——上次更新&#xff08;2023.07.13-23:07&#xff09; 迭代器&#xff08;iterator&#xff09; #include <iostream> #include <vector> #include <iterator> #include <algorithm>int main() { std::vector<int> e; std::copy(…

第二章编程模型(Cortex-M7 Processor Programmers Model)

第二章编程模型 本章描述了程序员模型。它包含以下部分: 关于2-2页的程序员模型。2-3页的操作和执行方式。指令集摘要见第2-4页。系统地址映射在2-5页。2-8页的独家监视器。处理器核心寄存器在第2-9页。例外情况见第2-10页。 2.1关于编程模型 本章概述了描述实现定义选项的…

力扣题目解析:生成奇数个字符的字符串的巧妙方法

本篇博客会讲解力扣“1374. 生成每种字符都是奇数个的字符串”的解题思路&#xff0c;这是题目链接。 这道题的解题思路很巧妙&#xff0c;它利用了字符串长度n的奇偶性&#xff1a; 如果n是奇数&#xff0c;那么就把字符串全部填充为’a’&#xff0c;这样每种字符都是奇数个…