设计模式学习笔记(十九)中介者模式

设计模式学习笔记(十九)中介者模式

引入

在各种游戏中我们需要进行组队,同一个队伍的成员则构成了一个聊天室,如果玩家与玩家之间直接通信,那么将导致高耦合性,并且调用也会非常的复杂。
![在这里插入图片描述](https://img-blog.csdnimg.cn/90409f46e9074157b6c737525e2b2f0b.png

从上图中我们可以看出,如果用户之间直接通信会非常复杂,若是在几千上万人的软件聊天室中,复杂度难以想象,基于这个现状,中介者模式应运而生。
在这里插入图片描述
上图表示了引入中介者之后用户与中介者的关系,中介者作为一个“第三者”,作用是将对象之间的交互行为脱离出来,交给中介者统一协调调用,改造之后用户与用户之间的多对多关系也就变成了用户与中介者一对多的关系。中介者模式是“迪米特法则”的一个典型应用。

概念

中介者模式(Mediator Pattern)是一种行为型设计模式,它通过引入一个中介者对象来解耦一组对象之间的交互。中介者模式促进了对象之间的松耦合,并使对象之间的通信更加简洁明确。

在中介者模式中,一组对象不再直接相互通信,而是通过中介者进行通信。对象将自己的信息发送给中介者,然后由中介者将这些信息传递给其他相关的对象。这样,对象之间的交互就不再是直接的点对点,而是借助中介者进行的。

中介者模式结构图
在这里插入图片描述
中介者模式包含以下角色:
Mediator(中介者):定义各个对象交互的接口,维护对象之间的关系,并协调它们的交互。
ConcreteMediator(具体中介者):实现中介者接口,具体协调各个对象之间的交互关系。
Colleague(同事对象):定义与其他同事对象通信的接口,与中介者进行交互。
ConcreteColleague(具体同事对象):实现同事对象接口,并与其他同事对象通过中介者进行通信。

中介者模式通过提供中转作用协调作用来降低对象之间的耦合度。
1、中转作用:通过将对象之间的通信交给中介者来实现,使得对象不再需要直接引用其他对象。这样可以减少对象之间的直接依赖关系,降低耦合度,从而提高系统的灵活性和可维护性。
2、协调作用:通过中介者封装和管理对象之间的关系和交互逻辑。当一个对象需要与其他对象进行交互时,它只需与中介者进行通信,而无需了解其他对象的具体实现细节。中介者利用封装在其内部的协调逻辑,对同事的请求进行进一步处理,从而实现同事之间的协调和分离。
通过中转作用和协调作用,中介者模式能够有效地降低系统的复杂性,提高系统的可扩展性和可维护性。它将对象间复杂的交互关系简化为多个与中介者的简单交互,使得系统结构更加清晰,代码更容易理解和修改。

示例

单个同事类示例

我们将使用上述案例聊天室的例子
在这里插入图片描述
1、在聊天室中介者中创建一个用户list,并为其创建添加用户发送消息的方法。
2、用户类的属性中包含用户基本信息以及聊天室中介者类,并为其初始化,初始化完成后,将自身添加到传入的聊天室实例中。
3、聊天室具体类中实现添加用户发送消息的方法,添加用户通过第2步中的初始化用户实例的构造器来调用,发送消息(sendMessage) 方法将调用第一步中的用户list,并传入发送的消息用户自身实例,调用接收消息方法即可。
4、实际上就是在中介者中声明用户列表添加用户的方法,在用户类中的构造器中初始化客户端传入的中介者,并调用中介者的添加用户的方法将自身穿进去。

代码示例:

//聊天室中介者接口
interface ChatRoomMediator {
    List<abstractUser> users = new ArrayList<>();
    void addUser(abstractUser user);    //增加用户
    void sendMessage(String message, abstractUser user);    //message:发送的消息 user:发送者信息
}

// 聊天室实现中介者接口
class ChatRoom implements ChatRoomMediator {
    //增加用户
    @Override
    public void addUser(abstractUser user) {
        users.add(user);
    }

    //message:发送的消息 user:发送者信息
    @Override
    public void sendMessage(String message, abstractUser user) {
        // 广播消息给所有其他用户
        for (abstractUser u : users) {
            if (u != user) {
                u.receiveMessage(message, user);
            }
        }
    }
}
// 抽象用户类
abstract class abstractUser {
    protected String name;
    protected ChatRoomMediator mediator;
    //初始化用户名、想要加入的聊天室(中介者)
    public abstractUser(String name,ChatRoomMediator mediator) {
        this.name = name;
        this.mediator = mediator;
    }
    public abstract void sendMessage(String message);
    public abstract void receiveMessage(String message,abstractUser user);

}
class User extends abstractUser{
    //初始化用户名、想要加入的聊天室(中介者),并将自身加入到聊天室中
    public User(String name,ChatRoomMediator mediator) {
        super(name,mediator);
        mediator.addUser(this);
    }

    @Override
    public void sendMessage(String message) {
        // 使用中介者发送消息
        mediator.sendMessage(message,this);
    }

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

客户端

 		//创建聊天室
        ChatRoomMediator mediator = new ChatRoom();
        //所有用户申请加入同一个聊天室
        abstractUser user1,user2,user3;
        user1 = new User("张三",mediator);
        user2 = new User("李四",mediator);
        user3 = new User("王五",mediator);

        System.out.println("----张三发消息-----");
        user1.sendMessage("zzzzzzz");

        System.out.println("----李四发消息-----");
        user2.sendMessage("lllllllll");

输出结果

----张三发消息-----
李四 received message: zzzzzzz
王五 received message: zzzzzzz
----李四发消息-----
张三 received message: lllllllll
王五 received message: lllllllll

同事类的扩展

假设除了普通的用户User,我们还增加了root用户类RootUser

class RootUser extends abstractUser{
    //初始化用户名、想要加入的聊天室(中介者),并将自身加入到聊天室中
    public RootUser(String name,ChatRoomMediator mediator) {
        super(name,mediator);
        mediator.addUser(this);
    }

    @Override
    public void sendMessage(String message) {
        // 使用中介者发送消息
        mediator.sendMessage(message,this);
    }

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

客户端

 		//创建聊天室
        ChatRoomMediator mediator = new ChatRoom();
        abstractUser user1,user2,user3;
        //所有用户申请加入同一个聊天室
        user1 = new RootUser("张三",mediator);
        user2 = new RootUser("李四",mediator);
        user3 = new User("王五",mediator);    //普通用户也可以与root用户使用同一个中介者

        System.out.println();

        System.out.println("----张三发消息-----");
        user1.sendMessage("zzzzzzz");

        System.out.println("----李四发消息-----");
        user2.sendMessage("lllllllll");

输出结果与示例一相同。

从上述示例我们能看出,中介者模式在多个同事类的情况下,可以通过中介者灵活的将其实例纳入“聊天室”中。因此,如果需要引入新的具体同事类,只需要继承抽象同事类并实现其中的方法即可,由于具体同事类之间并无直接的引用关系,因此原有所有同事类无须进行任何修改,它们与新增同事对象之间的交互可以通过修改或者增加具体中介者类来实现;如果需要在原有系统中增加新的具体中介者类,只需要继承抽象中介者类(或已有的具体中介者类)并覆盖其中定义的方法即可,在新的具体中介者中可以通过不同的方式来处理对象之间的交互,也可以增加对新增同事的引用和调用。

总结

优点:
1、解耦:中介者模式将对象之间的通信行为集中在一个中介者对象中,使得各个对象之间不直接相互引用,从而降低了它们之间的耦合度。
2、简化对象间交互:中介者模式通过将复杂的交互逻辑封装在中介者对象中,简化了对象之间的交互过程,使其更加直观和易于理解。
重用性:中介者模式将对象间的通信行为集中在一个中介者对象中,可以使得该中介者对象在不同的场景下被重用,减少了重复的代码编写。
3、扩展性:通过增加新的中介者对象或者修改现有中介者对象,可以比较灵活地改变对象间的交互方式。
4、减少子类生成:中介者将原本分布于多个对象间的行为集中在一起,改变这些行为只需生成新的中介者子类即可,这使各个同事类可被重用,无须对同事类进行扩展。

缺点:
1、中介者对象的复杂性:随着系统中对象的增多,中介者对象可能会变得很复杂,承担过多的责任。
2、单点故障问题:由于中介者对象集中管理了对象间的通信行为,所以如果中介者对象发生故障,可能会影响整个系统的正常运行。

适用场景:
1、当对象之间有复杂的交互逻辑,导致对象之间的耦合度很高时,可以考虑使用中介者模式来简化对象之间的交互。
2、当一组对象需要通过中介者进行集中调度和控制时,可以使用中介者模式。例如,多个部件之间需要相互协调工作的图形界面应用程序。
3、当系统中的对象分布在不同的类中,但又需要频繁地进行通信时,可以引入中介者模式来降低耦合度,并提高系统的可维护性。

总而言之,**中介者模式适用于对象之间有复杂的交互关系、需要减少耦合度和简化交互过程的场景。**通过引入中介者对象,可以降低系统的复杂性,并提高可维护性和扩展性。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值