设计模式(21)中介者模式

news2024/11/18 20:16:51

一、介绍:

1、定义:中介者模式(Mediator Pattern)是一种行为型设计模式,它通过引入一个中介者对象来降低多个对象之间的耦合度。在中介者模式中,各个对象之间不直接进行通信,而是通过中介者对象进行协调和通信。

2、组成结构:

(1)抽象中介者(Abstract Mediator):定义了中介者对象的接口,用于协调各个同事对象之间的交互。

(2)具体中介者(Concrete Mediator):实现了抽象中介者接口,负责协调各个同事对象的交互,并了解各个同事对象的具体实现。

(3)抽象同事类(Abstract Colleague):定义了同事对象的接口,通常持有一个中介者对象的引用,用于与中介者进行通信。

(4)具体同事类(Concrete Colleague):实现了抽象同事类的接口,实现自身的业务逻辑,并通过中介者对象进行与其他同事对象的通信。

// 抽象中介者
interface Mediator {
    void send(String message, Colleague colleague);
}
 
// 具体中介者
class ConcreteMediator implements Mediator {
    private Colleague colleague1;
    private Colleague colleague2;
    
    public void setColleague1(Colleague colleague1) {
        this.colleague1 = colleague1;
    }
    
    public void setColleague2(Colleague colleague2) {
        this.colleague2 = colleague2;
    }
    
    @Override
    public void send(String message, Colleague colleague) {
        if (colleague == colleague1) {
            colleague2.receive(message);
        } else {
            colleague1.receive(message);
        }
    }
}
 
// 抽象同事类
abstract class Colleague {
    protected Mediator mediator;
    
    public Colleague(Mediator mediator) {
        this.mediator = mediator;
    }
    
    public abstract void send(String message);
    
    public abstract void receive(String message);
}
 
// 具体同事类
class ConcreteColleague1 extends Colleague {
    public ConcreteColleague1(Mediator mediator) {
        super(mediator);
    }
    
    @Override
    public void send(String message) {
        mediator.send(message, this);
    }
    
    @Override
    public void receive(String message) {
        System.out.println("ConcreteColleague1 Received: " + message);
    }
}
 
class ConcreteColleague2 extends Colleague {
    public ConcreteColleague2(Mediator mediator) {
        super(mediator);
    }
    
    @Override
    public void send(String message) {
        mediator.send(message, this);
    }
    
    @Override
    public void receive(String message) {
        System.out.println("ConcreteColleague2 Received: " + message);
    }
}
 
// 客户端
public static void main(String[] args) {
        ConcreteMediator mediator = new ConcreteMediator();
        
        ConcreteColleague1 colleague1 = new ConcreteColleague1(mediator);
        ConcreteColleague2 colleague2 = new ConcreteColleague2(mediator);
        
        mediator.setColleague1(colleague1);
        mediator.setColleague2(colleague2);
        
        colleague1.send("msg from Colleague1");
        colleague2.send("msg from Colleague2");
    }

3、优点:

(1)降低耦合度:中介者模式将对象之间的交互集中在中介者对象中,减少了对象之间的直接依赖和耦合度,使系统更加灵活、可扩展和易于维护。

(2)简化对象间的通信:中介者模式通过引入中介者对象,将对象间复杂的相互通信转变为对象与中介者之间的简单交互,简化了对象间的通信逻辑。

(3)集中控制逻辑:中介者模式将对象间的交互逻辑集中在中介者对象中,使得系统的控制逻辑更加清晰明确。通过定义中介者对象来协调对象间的交互,可以更方便地修改和扩展系统的行为。

(4)促进代码重用:中介者模式将公共的交互逻辑封装在中介者对象中,可以被多个对象共享和复用,避免了代码的重复编写,提高了代码的可维护性和可复用性。

 4、适用场景:

(1)当一个系统中对象之间存在复杂的相互关系,导致对象间的交互逻辑难以维护和扩展时,可以考虑使用中介者模式来简化交互逻辑。

(2)当一个对象需要对多个对象进行操作或通知时,可以引入中介者模式来集中管理这些对象之间的交互。

(3)当系统中的对象之间存在循环依赖关系,不方便直接进行交互时,可以通过引入中介者对象来解决循环依赖问题。

二、demo:

1、房租中介:三个房东、三个租客。房东类和租客类互相影响,称为同事类。

(1)抽象同事类

import java.util.Objects;

/**
 * 抽象同事类(这里指房东、租客),有用户名称,以及消息发送、接收功能
 */
public abstract class Colleague {
    //租客、房东 都认识中介
    Mediator mediator;

    public String userName;

    public Colleague(String userName, Mediator mediator){
        this.userName = userName;
        this.mediator = mediator;
    }

    //这里对userName做equals和hashCode,是为了后面可以用contains判断方法
    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Colleague colleague = (Colleague) o;
        return Objects.equals(userName, colleague.userName);
    }

    @Override
    public int hashCode() {
        return Objects.hash(userName);
    }

    public void sendMsg(String msg){
        System.out.println("我"+this.userName+"发送消息");
    }

    public void receiveMsg(String msg,Colleague fromColleague){}
}

(2)具体同事类,房东和租客

//房东类
public class LandlordColleague extends Colleague{
    public LandlordColleague(String userName, Mediator mediator) {
        super(userName,mediator);
    }

    //发送消息,需要通知谁 谁可以收到由中介完成
    @Override
    public void sendMsg(String msg) {
        super.sendMsg(msg);
        mediator.notice(msg,this);
    }

    //收到中介发送的消息
    @Override
    public void receiveMsg(String msg,Colleague fromColleague) {
        System.out.println("房东"+this.userName+"收到"+fromColleague.userName+"发送的消息"+msg);
    }
}
import java.util.List;

//租客同事类
public class TenantColleague extends Colleague {
    public TenantColleague(String userName, Mediator mediator) {
        super(userName,mediator);
    }

    //发送消息,谁可以收到(所有房东)由中介完成
    @Override
    public void sendMsg(String msg) {
        super.sendMsg(msg);
        mediator.notice(msg,this);
    }

    //收到消息
    @Override
    public void receiveMsg(String msg,Colleague fromColleague) {
        System.out.println("租客"+this.userName+"收到"+fromColleague.userName+"发送的消息"+msg);
    }
}

(3)抽象中介

//抽象中介
public interface Mediator {
    //通知
    void notice(String msg,Colleague fromColleague);
}

(4)具体中介

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

/**
 * 房租中介
 */
public class RentMediator implements Mediator{

    //所有租客
    List<Colleague> tenantColleagues = new ArrayList<>();
    //所有房东
    List<Colleague> landlordColleagues = new ArrayList<>();

    //添加房东
    void addLandlord(Colleague colleague){
        this.landlordColleagues.add(colleague);
    }

    //添加租客
    void addTenantColleague(Colleague colleague){
        this.tenantColleagues.add(colleague);
    }

    /**
     * 通知
     * 通知所有房东or 租客
     * @param msg
     * @param fromColleague
     */
    @Override
    public void notice(String msg, Colleague fromColleague) {
        //房东发的,通知所有租客
        if(landlordColleagues.contains(fromColleague)){
            for(Colleague colleague : tenantColleagues){
                colleague.receiveMsg(msg,fromColleague);
            }
        }
        //租客发的,通知所有房东
        if(tenantColleagues.contains(fromColleague)){
            for(Colleague colleague : landlordColleagues){
                colleague.receiveMsg(msg,fromColleague);
            }
        }
    }
}

客户端:

public class Test {
    public static void main(String args[]){
        RentMediator rentMediator = new RentMediator();
        //房东管理
        LandlordColleague landlordColleague1 = new LandlordColleague("房东1",rentMediator);
        LandlordColleague landlordColleague2 = new LandlordColleague("房东2",rentMediator);
        LandlordColleague landlordColleague3 = new LandlordColleague("房东3",rentMediator);
        rentMediator.addLandlord(landlordColleague1);
        rentMediator.addLandlord(landlordColleague2);
        rentMediator.addLandlord(landlordColleague3);
        //租客管理
        TenantColleague tenantColleague1 = new TenantColleague("租客1",rentMediator);
        TenantColleague tenantColleague2 = new TenantColleague("租客2",rentMediator);
        TenantColleague tenantColleague3 = new TenantColleague("租客3",rentMediator);
        rentMediator.addTenantColleague(tenantColleague1);
        rentMediator.addTenantColleague(tenantColleague2);
        rentMediator.addTenantColleague(tenantColleague3);
        //
        tenantColleague2.sendMsg("寻找三室房源");
        System.out.println("******");
        landlordColleague3.sendMsg("发布新房源");
    }
}


输出:
我租客2发送消息
房东房东1收到租客2发送的消息寻找三室房源
房东房东2收到租客2发送的消息寻找三室房源
房东房东3收到租客2发送的消息寻找三室房源
******
我房东3发送消息
租客租客1收到房东3发送的消息发布新房源
租客租客2收到房东3发送的消息发布新房源
租客租客3收到房东3发送的消息发布新房源

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

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

相关文章

Nginx 实战指南:暴露出请求的真实 IP

&#x1f52d; 嗨&#xff0c;您好 &#x1f44b; 我是 vnjohn&#xff0c;在互联网企业担任 Java 开发&#xff0c;CSDN 优质创作者 &#x1f4d6; 推荐专栏&#xff1a;Spring、MySQL、Nacos、Java&#xff0c;后续其他专栏会持续优化更新迭代 &#x1f332;文章所在专栏&…

跑腿小程序开发解析:技术架构、接口设计和前沿趋势

随着生活节奏的加快和个人需求的增加&#xff0c;跑腿小程序成为了人们生活中不可或缺的一部分。从技术角度来看&#xff0c;一个高效、安全、以及用户友好的跑腿小程序是由多个关键要素构成的&#xff0c;包括技术架构、接口设计和前沿趋势。 技术架构 1. 前端技术选型 选择…

Windows Server 2016磁盘管理使用指南:看完即会!

如何打开Windows Server 2016磁盘管理器&#xff1f; 磁盘管理首先在Windows XP中引入&#xff0c;是一个Windows内置实用程序&#xff0c;可让你管理硬盘和关联的分区或卷。在Windows Server磁盘管理对硬盘进行分区非常方便。你可以通过以下方法之一访问它&#xff1a; 方…

数据库系统原理与实践 笔记 #6

文章目录 数据库系统原理与实践 笔记 #6数据库设计和E-R模型设计过程实体-联系模型实体集联系集联系集中实体的角色联系集的度属性复合属性 约束映射基数约束参与约束实体集的码联系集的码冗余属性 实体-联系图E-R图参与联系集中的实体集基数约束角色三元关系上的基数约束弱实体…

JMeter简单使用

JMeter是一个功能强大的开源性能测试工具&#xff0c;用于对各种应用程序、协议和服务器进行性能和负载测试。它被广泛用于测试Web应用程序的性能&#xff0c;并可以模拟多种负载条件和行为。 JMeter使用 添加线程组 设置线程组的配置 设置请求 配置请求 添加监听器 查看压…

Java微服务构建:打造健壮订单模型的完整指南

Java微服务构建一个健壮的订单模型(业务,规划&#xff0c;设计与实现) 在设计领域业务模型时&#xff0c;我们通常会追求理论完美&#xff0c;而忽略实践的脆弱性。尽管我们没有贬低领域建模的意图&#xff0c;但事实上&#xff0c;在电商技术发展多年之后&#xff0c;某些系统…

idea中启动多例项目配置

多实例启动 日常本地开发微服务项目时&#xff0c;博主想要验证一下网关的负载均衡以及感知服务上下线能力时&#xff0c;需要用到多实例启动。 那么什么是多实例启动嘞&#xff1f;简单说就是能在本地同时启动多个同一服务。打个比方项目中有一个 MobileApplication 服务&…

怎么压缩视频?试试这个方法

怎么压缩视频&#xff1f;我们都知道视频的内存比其他类型的文件都要大很多。那是因为视频的分辨率越高&#xff0c;所包含的像素点就越多&#xff0c;因此文件大小也就越大。而且一般来说&#xff0c;视频文件的时长都比较长&#xff0c;当视频的时间越长&#xff0c;那么视频…

RFID银行款箱智能管理应用解决方案

一、行业背景 随着金融业务的不断发展&#xff0c;金融物流的安全性成为越来越重要的问题&#xff0c;银行金库每天都有大量现金款箱的出入库和配送&#xff0c;如果无法确保及时准确地进行入库、库存控制和出库&#xff0c;将给银行带来巨大的风险&#xff0c;增加了银行的管…

堆栈与队列算法-八皇后问题的求解算法

目录 堆栈与队列算法-八皇后问题的求解算法 C代码 堆栈与队列算法-八皇后问题的求解算法 八皇后问题是一种常见的堆栈应用实例。在国际象棋中的皇后可以在没有限定一步走几格的前提下&#xff0c;对棋盘中的其他棋子直吃、横吃和对角斜吃&#xff08;左斜吃或右斜吃均可&…

博客模板博客模板

xservices-bpm-6.2.1.1.jar 本人详解 作者&#xff1a;王文峰&#xff0c;参加过 CSDN 2020年度博客之星&#xff0c;《Java王大师王天师》作者 公众号&#xff1a;山峯草堂&#xff0c;非技术多篇文章&#xff0c;专注于天道酬勤的 Java 开发问题、中国国学、传统文化和代码爱…

使用Objective-C和ASIHTTPRequest库进行Douban电影分析

概述 Douban是一个提供图书、音乐、电影等文化内容的社交网站&#xff0c;它的电影频道包含了大量的电影信息和用户评价。本文将介绍如何使用Objective-C语言和ASIHTTPRequest库进行Douban电影分析&#xff0c;包括如何获取电影数据、如何解析JSON格式的数据、如何使用代理IP技…

文心一言 VS 讯飞星火 VS chatgpt (124)-- 算法导论10.5 5题

五、用go语言&#xff0c;给定一个n结点的二叉树&#xff0c;写出一个 O(n)时间的非递归过程&#xff0c;将该树每个结点的关键字输出。要求除该树本身的存储空间外只能使用固定量的额外存储空间&#xff0c;且在过程中不得修改该树&#xff0c;即使是暂时的修改也不允许。 文…

ice和Dtls 传输的创建及1个简单的SFU转发实例

ice和Dtls 传输的创建及1个简单的SFU转发实例 licode中,webrtcconn基于dtlstransport 收发,而dtlstransport通过libnice作为底层。dtlstransport 使用了srtp加解密。文末给出一个简化的sfu实例的实现。对应的,看下M98的代码,更能理解为啥这么做: IceTransportInternal 与D…

Transformer模型原理

NLP预训练模型的架构大致可以分为三类&#xff1a; 1. Encoder-Decoder架构&#xff08;T5&#xff09;&#xff0c;seq2seq模型&#xff0c;RNN、LSTM网络 2. BERT&#xff1a;自编码语言模型&#xff0c;预测文本随机掩码 3. GPT&#xff1a; 自回归语言模型&#xff0c;预测…

Elasticsearch(一)---搭建

搭建es 不允许root用于运行 创建esuser用户&#xff1a; useradd esuser 设置密码 passwd esuser 让esuser拥有sudo的权限&#xff0c;需要修改/etc/sudoers文件 需要先给/etc/sudoers添加写的权限 [rootnode1 ~]# vim /etc/sudoers 改完之后将写权限删除 三台服务器上操…

“阿里巴巴按关键字搜索接口:一键获取海量商品信息,助力商家抢占市场先机!“

阿里巴巴按关键字搜索商品的接口是通过开放平台提供的API接口来实现的。要使用这个接口&#xff0c;需要进行以下步骤&#xff1a; 确认API接口的请求地址和所需参数&#xff1a;需要先查看API文档&#xff0c;了解所要访问的API接口的请求地址和请求参数&#xff0c;以便正确…

python随手小练13

题目1&#xff1a; 定义学员信息类&#xff0c;包含姓名、成绩属性&#xff0c;定义成绩打印方法 (90分及以上显示优秀&#xff0c;80分及以上显示良好&#xff0c;70分及以上显示中等&#xff0c;60分及以上显示合格&#xff0c;60分以下显示不及格) 具体操作&#xff1a; cl…

基于pyqt5和yolov8的智慧工地施工人工安全检测系统

基于pyqt5和yolov8的智慧工地施工人工安全检测系统 主要基于两者进行集成 在前面模型训练基础上&#xff0c;实现安全马甲、安全面具和安全帽的检测。 核心检测代码 def run(self):self.hilo_corriendo Truemodel YOLO("best.pt")cap cv2.VideoCapture(0)while…

安全生产管理系统助力企业安全细化管理

安全生产管理系统利用完整的安全生产管理体系&#xff0c;结合信息化、数字化和智能化等技术手段&#xff0c;将安全生产过程中的各个环节进行有效整合&#xff0c;使安全管理更加科学、规范和高效。 安全生产管理系统可以对企业安全生产进行全面、细致的管理。它能够实现对企…