Mediator 中介者模式

中介者模式(Mediator Pattern)是行为设计模式之一,它允许减少对象之间的直接通信,从而降低系统的耦合度。下面我将介绍中介者模式的意图、结构以及适用性。

意图

用一个中介对象来封装一系列的对象交互。中介者使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。

  • 封装一系列对象之间的交互。
  • 使这些对象不需要显式地相互引用,让它们可以松散耦合。
  • 可以独立地改变对象之间的交互。

结构

在这里插入图片描述

  • Mediator(中介者):定义了一个接口用于与各Colleague(同事)对象通信。
  • ConcreteMediator(具体中介者):实现 Mediator 接口,并协调 Colleague 对象之间的交互。
  • Colleague(同事):每个同事只知道自己的行为,对于其他同事的行为一无所知,但它们都认识中介者对象。
  • ConcreteColleague(具体同事):实现了 Colleague 的行为,并通过中介者与其他同事通信。

在这个结构图中:

  • Mediator 是中介者的接口,定义了用于同事间通信的方法。
  • ConcreteMediator 是实现了 Mediator 接口的具体中介者类,知道所有具体同事类,并协调它们之间的交互。
  • Colleague 是同事的基类或接口,通常会持有对 Mediator 的引用,并实现一些方法供其他同事通过中介者调用。
  • Colleague1Colleague2 是具体的同事类,每个同事只知道自己的行为,对于其他同事的行为则一无所知,所有的交互都必须通过中介者来进行。

适用性

  • 当一组对象以定义良好的方式相互通信时,你可以考虑使用中介者模式。中介者模式有助于封装这些交互。
  • 如果你不希望某些对象直接引用其他对象,即你想解耦这些对象,那么中介者模式可以帮助实现这一点。
  • 当你发现很难复用对象,因为它们紧密地联系在一起时,中介者模式可以用来分离这些对象,使得它们更容易被复用。
  • 在系统中存在大量的对象间交互时,使用中介者模式可以简化对象间的通信,同时避免了对象间的强耦合。

实例

家庭系统多设备通讯

下面是一个简单的例子,假设我们有一个家庭自动化系统,其中包括多个设备如灯光、空调和音响。这些设备需要能够互相通信,比如当安全系统被触发时,灯光会亮起,空调关闭,音响发出警报声。如果没有使用中介者模式,每个设备之间都需要两两建立连接,这会导致系统非常复杂。使用中介者模式后,所有的设备只需要与一个中心控制器(中介者)通信即可。

首先,定义一个中介者的接口:

public interface Mediator {
    void registerDevice(Device device);
    void command(String command, Device sender);
}

接着,创建具体的中介者实现类:

import java.util.HashMap;
import java.util.Map;

public class HomeAutomationMediator implements Mediator {
    private Map<String, Device> devices = new HashMap<>();

    @Override
    public void registerDevice(Device device) {
        devices.put(device.getName(), device);
        device.setMediator(this);
    }

    @Override
    public void command(String command, Device sender) {
        for (Map.Entry<String, Device> entry : devices.entrySet()) {
            if (!entry.getKey().equals(sender.getName())) { // 不对自己发送命令
                entry.getValue().executeCommand(command);
            }
        }
    }
}

然后,定义设备的接口:

public interface Device {
    String getName();
    void setMediator(Mediator mediator);
    void executeCommand(String command);
}

再创建一些具体设备的实现:

public class Light implements Device {
    private Mediator mediator;
    private String name;

    public Light(String name) {
        this.name = name;
    }

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

    @Override
    public void setMediator(Mediator mediator) {
        this.mediator = mediator;
    }

    @Override
    public void executeCommand(String command) {
        if ("ALARM".equals(command)) {
            System.out.println("Light: Turning on the lights.");
        } else if ("NORMAL".equals(command)) {
            System.out.println("Light: Turning off the lights.");
        }
    }
}

// 其他设备如AirConditioner, Stereo等类似实现

最后,在客户端代码中配置并运行这个系统:

public class Client {
    public static void main(String[] args) {
        Mediator homeMediator = new HomeAutomationMediator();

        Device light = new Light("Living Room Light");
        Device airConditioner = new AirConditioner("Living Room AC");
        Device stereo = new Stereo("Living Room Stereo");

        homeMediator.registerDevice(light);
        homeMediator.registerDevice(airConditioner);
        homeMediator.registerDevice(stereo);

        // 模拟外部事件,例如安全系统检测到入侵
        light.executeCommand("ALARM");
    }
}

在这个例子中,HomeAutomationMediator充当了所有设备间的中介者,减少了设备之间的直接依赖。当有事件发生时(如执行"ALARM"命令),相关的设备会接收到通知并做出响应。这种方式使得系统更易于扩展和维护。

聊天室

一个聊天室的例子。在这个例子中,多个用户(参与者)通过一个聊天室(中介者)进行交流。每个用户不需要知道其他用户的细节,他们只需要向聊天室发送消息,然后由聊天室负责将消息转发给所有在线的用户。

首先,定义中介者的接口:

public interface ChatRoom {
    void register(User user);
    void sendMessage(String message, User sender);
}

接着,创建具体的中介者实现类:

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

public class ConcreteChatRoom implements ChatRoom {
    private List<User> users = new ArrayList<>();

    @Override
    public void register(User user) {
        if (!users.contains(user)) {
            users.add(user);
            System.out.println(user.getName() + " has joined the chat.");
        }
    }

    @Override
    public void sendMessage(String message, User sender) {
        for (User user : users) {
            // 不对自己发送消息
            if (user != sender) {
                user.receive(message);
            }
        }
    }
}

然后,定义参与者的接口:

public interface User {
    String getName();
    void receive(String message);
    void send(String message, ChatRoom chatRoom);
}

再创建具体参与者的实现:

public class ConcreteUser implements User {
    private String name;
    private ChatRoom chatRoom;

    public ConcreteUser(String name, ChatRoom chatRoom) {
        this.name = name;
        this.chatRoom = chatRoom;
        chatRoom.register(this);
    }

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

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

    @Override
    public void send(String message, ChatRoom chatRoom) {
        System.out.println(name + " sends: " + message);
        chatRoom.sendMessage(message, this);
    }
}

最后,在客户端代码中配置并运行这个系统:

public class Client {
    public static void main(String[] args) {
        ChatRoom chatRoom = new ConcreteChatRoom();

        User john = new ConcreteUser("John", chatRoom);
        User jane = new ConcreteUser("Jane", chatRoom);
        User tom = new ConcreteUser("Tom", chatRoom);

        john.send("Hello, everyone!", chatRoom);
        jane.send("Hi, John! How are you?", chatRoom);
        tom.send("Hey, what's up?", chatRoom);
    }
}

在这个例子中,ConcreteChatRoom作为中介者,它管理着所有用户,并在有新消息时负责将消息广播给所有其他用户。用户之间不再直接通信,而是通过聊天室间接地进行交流。这样做的好处是减少了用户间的耦合度,使得系统更加灵活和易于扩展。例如,如果以后需要添加新的功能,如私聊或者群聊,只需要修改中介者的逻辑即可,而无需改变用户类的代码。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

老攀呀

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值