软件设计模式系列之十九——中介者模式

@

1 模式的定义

中介者模式是一种行为型设计模式,它用于降低对象之间的直接通信,通过引入一个中介者对象来管理对象之间的交互。这种模式有助于减少对象之间的耦合性,使系统更加可维护和扩展。中介者模式是Gang of Four(GoF)设计模式中的一员,旨在促进对象之间的松耦合关系,从而提高系统的灵活性。

2 举例说明

为了更好地理解中介者模式,让我们考虑一个简单的例子:一个多人在线聊天室应用程序。在这个应用程序中,有多个用户可以发送消息给其他用户,而不需要直接知道接收消息的用户是谁。中介者模式可以用来管理用户之间的消息传递。

在这个例子中,中介者充当聊天室的中心,所有用户都将消息发送到中介者,然后中介者负责将消息传递给适当的接收者。这样,用户之间不需要直接通信,而是通过中介者进行通信,从而降低了用户之间的耦合性。

3 结构

中介者模式的结构包括以下几个关键元素:

抽象中介者(Mediator):这是中介者模式的核心接口,它定义了中介者对象应该具备的方法,通常包括注册组件、发送消息等操作。

具体中介者(ConcreteMediator):具体中介者是抽象中介者的实现,它维护了对所有相关组件的引用,并负责协调它们之间的通信。

抽象组件(Colleague):抽象组件代表参与中介者模式的各个组件对象,它们通常具有一个指向中介者的引用,并定义了与其他组件对象通信的接口。

具体组件(ConcreteColleague):具体组件是抽象组件的实现,它们之间通过中介者来通信,而不是直接相互关联。

4 实现步骤

要实现中介者模式,您可以按照以下步骤进行:

定义抽象中介者接口:创建一个抽象中介者接口,其中包括方法来注册和发送消息。

创建具体中介者类:实现抽象中介者接口,管理所有具体组件对象的引用,并协调它们之间的通信。

定义抽象组件接口:创建一个抽象组件接口,其中包括方法来注册中介者和发送消息。

创建具体组件类:实现抽象组件接口,确保它们能够通过中介者对象进行通信。

在具体组件中使用中介者:在具体组件中使用中介者来发送消息,而不是直接与其他组件通信。

客户端代码:在客户端代码中创建中介者和组件对象,然后将组件对象注册到中介者中,以便它们可以相互通信。

5 代码实现

// 1. 定义抽象中介者接口
interface Mediator {
    void register(Colleague colleague);
    void send(String message, Colleague sender);
}

// 2. 创建具体中介者类
class ConcreteMediator implements Mediator {
    private List<Colleague> colleagues = new ArrayList<>();

    @Override
    public void register(Colleague colleague) {
        colleagues.add(colleague);
    }

    @Override
    public void send(String message, Colleague sender) {
        for (Colleague colleague : colleagues) {
            if (colleague != sender) {
                colleague.receive(message);
            }
        }
    }
}

// 3. 定义抽象组件接口
interface Colleague {
    void setMediator(Mediator mediator);
    void send(String message);
    void receive(String message);
}

// 4. 创建具体组件类
class ConcreteColleague implements Colleague {
    private Mediator mediator;
    private String name;

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

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

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

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

// 6. 客户端代码
public class Client {
    public static void main(String[] args) {
        Mediator mediator = new ConcreteMediator();

        Colleague colleague1 = new ConcreteColleague("User1");
        Colleague colleague2 = new ConcreteColleague("User2");
        Colleague colleague3 = new ConcreteColleague("User3");

        mediator.register(colleague1);
        mediator.register(colleague2);
        mediator.register(colleague3);

        colleague1.setMediator(mediator);
        colleague2.setMediator(mediator);
        colleague3.setMediator(mediator);

        colleague1.send("Hello, everyone!");
        colleague2.send("Hi there!");
    }
}

6 典型应用场景

中介者模式适用于以下场景:

多对多对象交互:当多个对象之间需要进行复杂的相互通信时,中介者模式可以帮助简化系统结构。

减少耦合性:当对象之间的直接耦合关系导致系统难以维护和扩展时,中介者模式可以降低对象之间的耦合度。

分布式系统:在分布式系统中,各个节点之间可能需要进行协同工作,中介者模式可以用于管理节点之间的通信。

7 优缺点

优点:

降低耦合性:中介者模式将对象之间的通信集中在一个中介者对象中,降低了对象之间的直接耦合,使系统更加灵活。

易于扩展:通过添加新的具体组件和中介者,可以轻松扩展系统,而无需修改现有代码。

集中控制:中介者模式允许将系统的控制逻辑集中在一个对象中,使系统更易于理解和维护。

缺点:

中介者对象复杂:随着系统的增长,中介者对象可能会变得复杂,包含大量的逻辑。

性能问题:由于中介者负责协调对象之间的通信,可能会导致性能问题,特别是在大规模系统中。

8 类似模式

与中介者模式类似的模式包括观察者模式和代理模式。虽然它们在某些方面具有相似性,但它们在用途和实现方式上有一些关键区别。

观察者模式(Observer Pattern):

观察者模式和中介者模式都处理对象之间的通信,但它们关注的侧重点不同。观察者模式是一对多的关系,其中一个主题对象(Subject)维护一组观察者(Observer),当主题对象的状态发生变化时,通知所有观察者。观察者之间通常不直接通信,而是通过主题对象。中介者模式关注多对多的对象通信,中介者充当对象之间的中心枢纽,协调它们的交互。观察者模式关注一对多的依赖关系,其中主题对象维护观察者列表,但观察者之间不直接通信,而是通过主题对象。

代理模式(Proxy Pattern):

代理模式和中介者模式都涉及到控制对象之间的访问和交互。代理充当目标对象的代表,可以控制对目标对象的访问。中介者模式关注多个对象之间的通信和协调,它引入一个中介者对象,使对象之间的关系更加松散。代理模式关注对单个对象的访问控制,代理对象通常封装了目标对象的功能,但并不协调多个对象之间的交互。

虽然这些模式都有助于降低对象之间的耦合性,但它们的关注点和应用场景略有不同。中介者模式用于协调多个对象之间的复杂通信,观察者模式用于建立一对多的依赖关系,代理模式用于控制对单个对象的访问,而发布-订阅模式用于发布和订阅事件或消息。选择哪种模式取决于具体的设计需求和问题背景。

9 小结

中介者模式是一种有助于管理多个对象之间通信的强大工具。通过引入中介者对象,它能够降低对象之间的耦合度,使系统更加灵活、易于扩展和维护。在设计软件系统时,考虑使用中介者模式来促进对象之间的松耦合关系,提高系统的可维护性和可扩展性。

posted @ 2023-09-29 19:58  cooldream2009  阅读(451)  评论(0编辑  收藏  举报