首页 > 其他分享 >中介者模式详解:概念、优点及实例

中介者模式详解:概念、优点及实例

时间:2024-07-20 17:57:52浏览次数:9  
标签:String 实例 mediator void 中介 详解 message public

目录

中介者模式

中介者模式是一种行为设计模式, 能让你减少对象之间混乱无序的依赖关系。 该模式会限制对象之间的直接交互, 迫使它们通过一个中介者对象进行合作。

中介者模式结构

在这里插入图片描述

  1. 组件 (Component) 是各种包含业务逻辑的类。 每个组件都有一个指向中介者的引用, 该引用被声明为中介者接口类型。 组件不知道中介者实际所属的类, 因此你可通过将其连接到不同的中介者以使其能在其他程序中复用。

  2. 中介者 (Mediator) 接口声明了与组件交流的方法, 但通常仅包括一个通知方法。 组件可将任意上下文 (包括自己的对象) 作为该方法的参数, 只有这样接收组件和发送者类之间才不会耦合。

  3. 具体中介者 (Concrete Mediator) 封装了多种组件间的关系。 具体中介者通常会保存所有组件的引用并对其进行管理, 甚至有时会对其生命周期进行管理。

  4. 组件并不知道其他组件的情况。 如果组件内发生了重要事件, 它只能通知中介者。 中介者收到通知后能轻易地确定发送者, 这或许已足以判断接下来需要触发的组件了。

    对于组件来说, 中介者看上去完全就是一个黑箱。 发送者不知道最终会由谁来处理自己的请求, 接收者也不知道最初是谁发出了请求。

中介者模式通用代码:

//抽象中介者
abstract class Mediator{
    //定义同事类
    protected List<Colleague> colleagues = new ArrayList<>();
    
    public void addColleague(Colleague colleague){
    colleagues.add(colleague);    
    }
    
    public abstract void sendMessage(String message,Colleague sender);
}

//具体中介类,一般只有一个。
class ConcreteMediator extends Mediator{
    @Override
    public void sendMessage(String message, Colleague sender) {
        for (Colleague colleague : colleagues) {
            if (colleague != sender) {
                colleague.receiveMessage(message);
            }
        }
    }
}

//抽象同事类
abstract class Colleague{
    protected Mediator mediator;
    public Colleague(Mediator mediator){
    this.mediator = mediator;
    mediator.addColleague(this);
}
    public abstract void sendMessage(String name);
    public abstract void receiveMessage(String message);
}

// 具体同事类1
class ConcreteColleague1 extends Colleague {
    public ConcreteColleague1(Mediator mediator) {
        super(mediator);
    }

    @Override
    public void sendMessage(String message) {
        System.out.println("Colleague1 sends: " + message);
        mediator.sendMessage(message, this);
    }

    @Override
    public void receiveMessage(String message) {
        System.out.println("Colleague1 received: " + message);
    }
}

// 具体同事类2
class ConcreteColleague2 extends Colleague {
    public ConcreteColleague2(Mediator mediator) {
        super(mediator);
    }

    @Override
    public void sendMessage(String message) {
        System.out.println("Colleague2 sends: " + message);
        mediator.sendMessage(message, this);
    }

    @Override
    public void receiveMessage(String message) {
        System.out.println("Colleague2 received: " + message);
    }
}

中介者模式适用场景

  1. 当一些对象和其他对象紧密耦合以致难以对其进行修改时, 可使用中介者模式。

    该模式让你将对象间的所有关系抽取成为一个单独的类, 以使对于特定组件的修改工作独立于其他组件。

  2. 当组件因过于依赖其他组件而无法在不同应用中复用时, 可使用中介者模式。

    应用中介者模式后, 每个组件不再知晓其他组件的情况。 尽管这些组件无法直接交流, 但它们仍可通过中介者对象进行间接交流。 如果你希望在不同应用中复用一个组件, 则需要为其提供一个新的中介者类。

  3. 如果为了能在不同情景下复用一些基本行为, 导致你需要被迫创建大量组件子类时, 可使用中介者模式。

    由于所有组件间关系都被包含在中介者中, 因此你无需修改组件就能方便地新建中介者类以定义新的组件合作方式。
    在这里插入图片描述

中介者模式优缺点

中介者模式优点:

  • 单一职责原则。 你可以将多个组件间的交流抽取到同一位置, 使其更易于理解和维护。

  • 开闭原则。 你无需修改实际组件就能增加新的中介者。

  • 你可以减轻应用中多个组件间的耦合情况。

  • 你可以更方便地复用各个组件。

中介者模式缺点:

  • 中介者会膨胀得很大,逻辑复杂。一段时间后,可能会演化为上帝对象。

练手题目

题目描述

小明正在设计一个简单的多人聊天室系统,有多个用户和一个聊天室中介者,用户通过中介者进行聊天,请你帮他完成这个系统的设计。

输入描述

第一行包括一个整数N,表示用户的数量(1 <= N <= 100) 第二行是N个用户,比如User1 User2 User3,用空格分隔 第三行开始,每行包含两个字符串,表示消息的发出者和消息内容,用空格分隔

输出描述

对于每个用户,输出一行,包含该用户收到的所有消息内容。

在这里插入图片描述

题解

初始解法:

import java.util.*;

// 抽象中介者类
abstract class Mediator {
    protected List<Colleague> colleagues = new ArrayList<>();
    
    // 添加同事到列表
    public void addColleague(Colleague colleague) {
        colleagues.add(colleague);
    }
    
    // 抽象方法:发送消息
    public abstract void sendMessage(String name, String message, Colleague sender);
}

// 具体中介者类
class ConcreteMediator extends Mediator {
    // 实现发送消息方法
    @Override
    public void sendMessage(String name, String message, Colleague sender) {
        // 遍历所有同事,将消息发送给除了发送者之外的所有人
        for (Colleague c : colleagues) {
            if (c != sender) {
                c.receiveMessage(name, message);
            }
        }
    }
}

// 抽象同事类
abstract class Colleague {
    protected Mediator mediator;
    protected String name;

    // 构造函数
    public Colleague(String name, Mediator mediator) {
        this.name = name;
        this.mediator = mediator;
        mediator.addColleague(this);
    }

    // 抽象方法:发送消息
    public abstract void sendMessage(String message);
    // 抽象方法:接收消息
    public abstract void receiveMessage(String senderName, String message);
}

// 具体同事类
class ConcreteColleague extends Colleague {
    public ConcreteColleague(String name, Mediator mediator) {
        super(name, mediator);
    }
    
    // 实现发送消息方法
    @Override
    public void sendMessage(String message) {
        mediator.sendMessage(this.name, message, this);
    }
    
    // 实现接收消息方法
    @Override
    public void receiveMessage(String senderName, String message) {
        System.out.println(this.name + " received: " + message);
    }
}

// 主类
public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
    
        // 读取用户数量
        int n = scanner.nextInt();
        scanner.nextLine(); 
        // 读取用户名
        String[] users = scanner.nextLine().split(" ");
        
        // 创建中介者
        Mediator mediator = new ConcreteMediator();
        // 创建用于存储同事对象的映射
        Map<String, Colleague> colleagues = new HashMap<>();
        
        // 创建所有用户的同事对象
        for (String user : users) {
            colleagues.put(user, new ConcreteColleague(user, mediator));
        }
        
        // 读取并处理消息
        while (scanner.hasNextLine()) {
            String line = scanner.nextLine();
            String[] parts = line.split(" ", 2);
            if (parts.length < 2) break;
            
            String senderName = parts[0];
            String message = parts[1];
            
            // 获取发送者并发送消息
            Colleague sender = colleagues.get(senderName);
            if (sender != null) {
                sender.sendMessage(message);
            }
        }
        
        scanner.close();
    }
}

优化后:

import java.util.*;

// 中介者接口
interface Mediator {
    void sendMessage(String message, String sender);
    void addUser(User user);
}

// 具体中介者
class ChatMediator implements Mediator {
    private List<User> users = new ArrayList<>();

    @Override
    public void sendMessage(String message, String sender) {
        for (User user : users) {
            if (!user.getName().equals(sender)) {
                user.receive(message);  
            }
        }
    }

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

// 用户接口
interface User {
    void send(String message);
    void receive(String message);
    String getName();
}

// 具体用户
class ChatUser implements User {
    private String name;
    private Mediator mediator;

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

    @Override
    public void send(String message) {
        mediator.sendMessage(message, this.name);
    }

    @Override
    public void receive(String message) {
        System.out.println(this.name + " received: " + message);
    }

    @Override
    public String getName() {
        return this.name;
    }
}

public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        Mediator mediator = new ChatMediator();
        Map<String, User> users = new HashMap<>();

        int n = scanner.nextInt();
        scanner.nextLine(); 
        String[] userNames = scanner.nextLine().split(" ");

        for (String name : userNames) {
            users.put(name, new ChatUser(name, mediator));
        }

        while (scanner.hasNextLine()) {
            String line = scanner.nextLine();
            String[] parts = line.split(" ", 2);
            if (parts.length < 2) break;

            String sender = parts[0];
            String message = parts[1];
            User user = users.get(sender);
            if (user != null) {
                user.send(message);
            }
        }

        scanner.close();
    }
}

相关文章

  • C语言-“关系”,“条件”,“逻辑”操作符详解
    目录关系操作符 “==”与“=”的区别 多个关系运算符不宜连用多个关系运算符判断值是否在中间的写法条件操作符逻辑操作符逻辑取反操作符:!逻辑与运算符:&& 逻辑或运算符:||练习:闰年的判断短路 关系操作符c语言用于比较的表达式,称为“关系表达式”(relational......
  • Java中的枚举详解
    文章目录概述使用枚举枚举的实现枚举的性能枚举与常量枚举集合类枚举与泛型枚举与反射概述枚举在Java中是一种特殊的类,用来定义一组固定的常量。它在Java5中引入,提供了一种类型安全的方式来定义和使用常量集合。尽管enum看起来像是新的数据类型,但它实际上是一个受限......
  • 【Python】使用库 -- 详解
    库就是别人已经写好了的代码,可以让我们直接拿来用。一个编程语言能不能流行起来,一方面取决于语法是否简单方便容易学习,一方面取决于生态是否完备。所谓的“生态” 指的就是语言是否有足够丰富的库,来应对各种各样的场景。在实际开发中,也并非所有的代码都自己手写,而是要充分利......
  • 【数据结构初阶】顺序表三道经典算法题(详解+图例)
    Hello!很高兴又见到你了~~~看看今天要学点什么来充实大脑吧——目录1、移除元素【思路+图解】 【总结】2、删除有序数组中的重复项【思路+图解】【总结】3、合并两个有序数组【思路+图解】【总结】 至此结束,ShowTime!1、移除元素【思路+图解】 ......
  • 【数据结构】详解堆
    一、堆的概念堆(Heap)是计算机科学中一类特殊的数据结构的统称。堆通常是一个可以被看做一棵完全二叉树的数组对象。堆是非线性数据结构,相当于一维数组,有两个直接后继。如果有一个关键码的集合K={k₀,k₁,k₂,k₃,…,kₙ₋₁ },把它的所有元素按完全二叉树的顺序存储方......
  • 【数据结构】超详解二叉树
    1、树的概念及结构堆与树的结构类似堆的概念及代码实现-CSDN博客树是一种非线性的数据结构,它是由n(n>=0)个有限结点组成一个具有层次关系的集合。把它叫做树是因为它看起来像一棵倒挂的树,也就是说它是根朝上,而叶朝下的。有一个特殊的结点,称为根结点,根结点没有前驱结点除......
  • C语言指针详解(进阶)
    二、指针的进阶    本章重点:            1.字符指针        2.数组指针        3.指针数组        4.数组传参和指针传参        5.函数指针        6.函数指针数组    ......
  • Linux系统安装的详细步骤详解
    在VM虚拟机上安装Linux系统全过程,闭眼跟着走就行!!!1、准备好VMwareWorestation虚拟机软件和Linux系统的映像文件2、点击创建新的虚拟机3、在新建虚拟机向导中,选择典型安装模式。典型安装模式可以通过几个简单的步骤快速安装虚拟机,更方便操作。点击下一步。4、在安装来源......
  • Java NIO 快速入门:Java 非阻塞 IO 编程详解
    一、NIO简介1.概述介绍:JavaNIO(NewInput/Output)是从Java1.4开始引入的一组新的IO库,旨在替代传统的阻塞式IO。NIO提供了更高效的IO操作,支持非阻塞模式和多路复用,适用于高并发场景。概述:NIO中通过Buffer作为缓存区,Channel作为数据通道来传输数据进行数据通讯,通过S......
  • 详解Nacos集群搭建
    目录前言1.集群结构图 2.搭建集群2.1初始化数据库 2.2下载nacos 2.3配置Nacos2.4启动2.5nginx反向代理2.6优化前言在我们日常的开发当中,用的都是单点Nacos,这种模式,我们自己开发测试玩一玩还可以,但是到了企业的生产环境之下,你还这么玩的话,那肯定是要出......