Introduction to the intermediary model

Concept :

Mediator Pattern is a behavioral design pattern that decouples interactions between multiple related objects by introducing a mediator object. A mediator acts as a coordinator between multiple objects so that these objects do not need to communicate directly with each other, but through communication with the mediator. The mediator pattern is used to encapsulate the complex interaction logic of a group of related objects into a single class (the mediator). This class is responsible for coordinating and managing communication between these objects and providing a unified interface for use by other objects.

Features :

  1. Decoupling related objects: Reduce direct dependencies between related objects by introducing a mediator.
  2. Centralized control logic: Centralize the management and processing of complex interaction logic in one class (i.e. mediator).
  3. Promote scalability: When adding new or modifying existing related objects, you only need to modify or extend the specific implementation class without changing other parts.

Advantages :

  1. Reduce many-to-many relationships: Transform the original complex and confusing many-to-many relationships into simple, clear, easy-to-understand, and easy-to-maintain one-to-many relationships.
  2. Improved system flexibility: Since each colleague class only depends on the abstract Mediator class, new mediators can be added without modifying the colleague class.
  3. Reduced coupling between objects: Each colleague class only needs to know the mediator object, without knowing the specific details of other colleague classes.

Disadvantages :

  1. The mediator pattern makes the mediator itself complex because it needs to handle the interaction logic between multiple related objects.
  2. When there are too many related objects in the system, the mediator may become too large and complex.

Applicable scenarios :

  1. There are complex and tightly coupled relationships between various objects within the system.
  2. An action affects other related objects, and it is desirable to reduce these interdependencies.
  3. It is necessary to centrally control the interaction logic between a group of related objects.

Implementation method :

Based on interface implementation

Implementation principle:

Define an abstract Mediator interface to constrain the concrete Mediator class and declare various coordination methods in it. Then create a specific Mediator class to implement the interface, and manage and coordinate the communication and interaction logic between related objects.

Implementation code:

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

// 中介者接口
interface Mediator {
    void sendMessage(String message, Colleague colleague);
    void addColleague(Colleague colleague);
}

// 具体中介者类
class ConcreteMediator implements Mediator {
    private List<Colleague> colleagues;

    public ConcreteMediator() {
        this.colleagues = new ArrayList<>();
    }

    public void addColleague(Colleague colleague) {
        colleagues.add(colleague);
    }

    @Override
    public void sendMessage(String message, Colleague colleague) {
        // 将消息广播给其他同事对象(除了发送方自身)
        for (Colleague c : colleagues) {
            if (c != colleague) {
                c.receiveMessage(message);
            }
        }
    }
}

// 同事类接口
interface Colleague {
    void receiveMessage(String message);

    void sendMessage(String message);
}

// 具体同事类A
class ConcreteColleagueA implements Colleague {

    private Mediator mediator;

    public ConcreteColleagueA(Mediator mediator){
        this.mediator=mediator;
        mediator.addColleague(this);
    }

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

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

// 具体同事类B
class ConcreteColleagueB implements Colleague {

    private Mediator mediator;

    public ConcreteColleagueB(Mediator mediator){
        this.mediator=mediator;
        mediator.addColleague(this);
    }

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

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

public class Main {

    public static void main(String[] args) {
        ConcreteMediator mediator = new ConcreteMediator();

        Colleague colleagueA = new ConcreteColleagueA(mediator);
        Colleague colleagueB = new ConcreteColleagueB(mediator);

        colleagueA.sendMessage("Hello, how are you?");
        colleagueB.sendMessage("I'm fine, thank you!");
    }
}

In the above example, we defined a mediator interface  Mediato r and a concrete implementation class  ConcreteMediato r . Then create two colleague classes  ConcreteColleagu e A and  ConcreteColleagu e B and pass the mediator object in their constructor. When a colleague object needs to send a message, it will be broadcast through the mediator and notify other related objects.

Based on event mechanism

The mediator pattern based on the event mechanism is implemented by using the observer pattern as the basis, using the mediator class as the publisher ( Publisher ), and other related objects as subscribers ( Subscriber ). When an object changes, the mediator publishes corresponding events to notify other related objects to perform corresponding operations.

Implementation principle:

  1. Define an abstract mediator interface, which contains methods such as registration, deregistration, and broadcast events.
  2. Create a concrete mediator class and implement the abstract interface, maintain a list of subscribers in it, and implement methods such as registration, deregistration, and broadcast events.
  3. Define the subscriber interface, which contains methods for handling events.
  4. Create multiple concrete subscriber classes and implement the subscriber interface, in which specific logic for handling different types of events is defined.
  5. When an object needs to send a message, call the mediator's broadcast event method, traverse all subscribers within the method, and call the processing method of the corresponding subscriber according to different types.

Implementation code:

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

// 中介者接口
interface Mediator {
    void register(String eventType, Subscriber subscriber);

    void unregister(String eventType, Subscriber subscriber);

    void broadcastEvent(String eventType, Object data);
}

// 具体中介者类
class ConcreteMediator implements Mediator {
    private Map<String, List<Subscriber>> subscribers;

    public ConcreteMediator() {
        this.subscribers = new HashMap<>();
    }

    @Override
    public void register(String eventType, Subscriber subscriber) {
        if (!subscribers.containsKey(eventType)) {
            subscribers.put(eventType, new ArrayList<>());
        }
        subscribers.get(eventType).add(subscriber);
    }

    @Override
    public void unregister(String eventType, Subscriber subscriber) {
        if (subscribers.containsKey(eventType)) {
            subscribers.get(eventType).remove(subscriber);
            if (subscribers.get(eventType).isEmpty()) { // 如果没有订阅者,移除该事件类型的列表
                subscribers.remove(eventType);
            }
        }
    }

    @Override
    public void broadcastEvent(String eventType, Object data) {
        if (subscribers.containsKey(eventType)) {
            for (Subscriber s : subscribers.get(eventType)) {
                s.handleEvent(data);
            }
        }
    }

}

// 订阅器接口
interface Subscriber {

    void handleEvent(Object data);

}

// 具体订阅器类A
class ConcreteSubscriberA implements Subscriber{

    @Override
    public void handleEvent(Object data){
        System.out.println("ConcreteSubscriber A received: " +data );
    }

}

// 具体订阅器类B
class ConcreteSubscriberB implements Subscriber{

    @Override

    public void handleEvent(Object data){
        System.out.println("ConcreteSubscriberB received: " +data );
    }
}


public class Main {

    public static void main(String[] args) {

        ConcreteMediator mediator = new ConcreteMediator();

        Subscriber subscriberA = new ConcreteSubscriberA();
        Subscriber subscriberB = new ConcreteSubscriberB();

        mediator.register("event1", subscriberA);
        mediator.register("event2", subscriberB);

        // 发送事件通知
        mediator.broadcastEvent("event1", "Hello, how are you?");
        mediator.broadcastEvent("event2", "I'm fine, thank you!");

        // 解注册订阅器
        mediator.unregister("event1", subscriberA);

        // 再次发送事件通知,只有subscriberB会接收到
        mediator.broadcastEvent("event1","This message won't be received by any subscribers");
        mediator.broadcastEvent("event2","This message will be received by only one subscriber");
    }
}

In the above example, we defined a mediator interface  Mediato r and a concrete implementation class  ConcreteMediato r . Then two subscriber classes  ConcreteSubscribere  A and  ConcreteSubscribere  B were created , and specific logic for handling different types of events was implemented in them. When you need to send a message, call the mediator's broadcast event method, traverse all subscribers within this method, and call the processing method of the corresponding subscriber according to different types.

Guess you like

Origin blog.csdn.net/aidscooler/article/details/132800862