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

news/2024/11/9 14:41:17

目录

一、基础概念

二、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.niftyadmin.cn/n/4557688.html

相关文章

SpringMVC无法找到/实例化Controller IDEA中有图标可以点进去

Tomcat启动正常Maven项目查看Maven项目中build标签下是否有resources标签&#xff0c;如果有则去掉或者把相应的资源的路劲都写上去&#xff0c;如果只写了下面的其中一个&#xff0c;那么会只包含那一个,详情请百度resources标签具体信息 <resources><resource>&l…

CSS 解决方案

1. 伪元素&#xff1a;清除浮动 给需要清除浮动的元素添加类名 clearfix 即可.clearfix::after {content: ;display: block;height: 0;line-height: 0;clear: both;visibility: hidden; }.clearfix {zoom: 1; } 2. 伪元素&#xff1a;实心小三角 .box::after {content: ;displa…

51单片机开始要学汇编吗

那就要看它的编译器的效率了 汇编和C各有千秋 都不可能有人拿他做OS ||| 汇编是要懂一些 但如果你能够都比较通的话就更好了 可以最大限度的利用单片机那可怜的存储空间 &#xff08;再说平台移植是指的在相同硬件结构下不同操作系统间的 编程最好用汇编 C所谓的平台移植性在某…

java volatile与锁 个人理解

书上意思: 当把变量声明为volatile类型后&#xff0c;编译器与运行时都会注意到这个变量是共享的&#xff0c;因此不会将该变量上的操作与其他内存操作一起重排序&#xff0c;volatile变量不会被缓存在寄存器或者对其他处理器不可见的地方&#xff0c;因此在读取volatile类型的…

【Linux 运维】linux系统关机、重启、注销命令

linux 关机、重启、注销命令&#xff1a; 关机命令&#xff1a; shutdown -h now 立刻关机&#xff08;生产常用&#xff09;shutdown -h 1 一分钟后关机 ( shutdown -c 可以将刚刚shutdown设置的指令取消取消)halt 立即停止系统&#xff0c;需要人工关闭电源&…

Hdoop 启动:localhost: Error: JAVA_HOME is not set and could not be found.

参考教程&#xff1a; http://hadoop.apache.org/docs/current/hadoop-project-dist/hadoop-common/SingleCluster.html 其中有 Prepare to Start the Hadoop Cluster Unpack the downloaded Hadoop distribution. In the distribution, edit the file etc/hadoop/hadoop-en…

ubantu(linux) eclipse 打不开 oom stackoverflow 的原因之一

工作空间日志提示&#xff1a; org.osgi.framework.BundleException: Exception in org.eclipse.core.resources.ResourcesPlugin.start() of bundle org.eclipse.core.resources. 极大的可能就是因为选择了默认的工作空间&#xff0c;而刚好就是那个默认空间因为&#xff0c…

使用JMX监控Kafka

监控数据源 JMX RMI方式启动Broker,Consumer,Producer -ea -Dcom.sun.management.jmxremote.authenticatefalse -Dcom.sun.management.jmxremote.sslfalse -Dcom.sun.management.jmxremote.port9996 通过JMX RMI方式连接 service:jmx:rmi:///jndi/rmi://127.0.0.1:9998/jmxrmi …