The mediator pattern in the design pattern --- Mediator Pattern

schema definition

The Mediator pattern is defined as follows:

Define an object that encapsulates how a set of objects interact.Mediator promotes loose coupling by keeping objects from referring to each other explicitly,and it lets you vary their interaction independently.

Encapsulate a series of object interactions with an intermediary object. The intermediary makes the objects do not need to interact explicitly, so that the coupling is loose, and the interaction between them can be changed independently.

Types of

Behavior

Pattern usage scenarios

The intermediary mode is suitable for the situation of tight coupling between multiple objects. The standard of tight coupling is: a spider web structure appears in the class diagram. This helps to organize the spider web structure into a star structure, making the originally complicated and chaotic relationships clear and simple.

actual use

The intermediary mode is also called the mediator mode. It is very confusing for an object to communicate with N objects. If you join a scheduling center, all classes will communicate with the center, and the center will handle whatever it says, isn't it very convenient?

  • Airport Control Center

    This is a concrete mediator

  • MVC framework

    In the MVC framework, C (Controller) is an intermediary. Its role is to isolate M(Model, business logic) from V(View, view), cooperate with M and V, and interact with the view represented by M and V. , reducing the dependencies of M and V. The MVC framework has become very popular, which is also a manifestation of the advantages of the intermediary model

  • Intermediary service

    Now there are a lot of intermediary services, such as renting a house and going abroad. These are the concrete manifestations of the intermediary model. For example, if you want to rent a house, if there is no real estate agency, you have to find it one by one, or sign a contract with the landlord, check the furniture, water, electricity, gas, etc., if there is an intermediary, then you only need to inform the intermediary of your requirements , After seeing the house, you can directly sign the contract, but looking for a house, negotiating the price with the landlord, checking the furniture, water, electricity, gas, Internet TV, etc., can all be handled by the intermediary for you, isn’t it very convenient?

UML class diagram

Character introduction

Mediator – abstract mediator role
The abstract intermediary role defines a unified interface for communication among colleagues.

Concrete Mediator – specific mediator role
The specific intermediary role realizes collaborative behavior by coordinating the roles of colleagues, so it must depend on the roles of colleagues.

Colleague – the role of a colleague
Each colleague role knows the mediator role, and when communicating with other colleague roles, it must cooperate through the mediator role.
The behavior of each colleague class is divided into two types: one is the behavior of the colleague itself, which is called a self-act (Self-Method); the second is a behavior that must rely on an intermediary to complete, called a dependent behavior (Dep- Method).

Generic Source Code for Patterns

Mediator class:

public abstract class Mediator {

    protected ConcreteColleague1 c1;
    protected ConcreteColleague2 c2;

    public ConcreteColleague1 getC1() {
        return c1;
    }
    public void setC1(ConcreteColleague1 c1) {
        this.c1 = c1;
    }
    public ConcreteColleague2 getC2() {
        return c2;
    }
    public void setC2(ConcreteColleague2 c2) {
        this.c2 = c2;
    }

    public abstract void doSomething1();
    public abstract void doSomething2();
}

ConcreteMediator class:

public class ConcreteMediator extends Mediator {

    @Override
    public void doSomething1() {
        // TODO Auto-generated method stub
        System.out.println("ConcreteMediator----doSomething1()");
        super.c1.doSelfMethod();
        super.c2.doSelfMethod();
    }

    @Override
    public void doSomething2() {
        // TODO Auto-generated method stub
        System.out.println("ConcreteMediator----doSomething2()");
        super.c1.doSelfMethod();
        super.c2.doSelfMethod();
    }
}

Colleague class:

public abstract class Colleague {

    protected Mediator mediator;

    public Colleague(Mediator _mediator){
        this.mediator = _mediator;
    }

    public abstract void doSelfMethod();
    public abstract void doDepMethod();
}

Specific colleagues:

ConcreteColleague1:

public class ConcreteColleague1 extends Colleague {

    public ConcreteColleague1(Mediator _mediator) {
        super(_mediator);
        // TODO Auto-generated constructor stub
    }

    @Override
    public void doSelfMethod() {
        // TODO Auto-generated method stub
        System.out.println("ConcreteColleague1----doSelfMethod()");
    }

    @Override
    public void doDepMethod() {
        // TODO Auto-generated method stub
        System.out.println("ConcreteColleague1----doDepMethod()");
        super.mediator.doSomething1();
        //super.mediator.doSomething2();
    }
}

ConcreteColleague2:

public class ConcreteColleague2 extends Colleague {

    public ConcreteColleague2(Mediator _mediator) {
        super(_mediator);
        // TODO Auto-generated constructor stub
    }

    @Override
    public void doSelfMethod() {
        // TODO Auto-generated method stub
        System.out.println("ConcreteColleague2----doSelfMethod()");
    }

    @Override
    public void doDepMethod() {
        // TODO Auto-generated method stub
        System.out.println("ConcreteColleague2----doDepMethod()");
        //super.mediator.doSomething1();
        super.mediator.doSomething2();
    }
}

Client class:

public class Client {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Mediator mediator = new ConcreteMediator();     
        ConcreteColleague1 colleague1 = new ConcreteColleague1(mediator);
        ConcreteColleague2 colleague2 = new ConcreteColleague2(mediator);

        mediator.setC1(colleague1); 
        mediator.setC2(colleague2);

        System.out.println("-------------------------------------");    
        colleague1.doSelfMethod();
        System.out.println("-------------------------------------");
        colleague1.doDepMethod();
        System.out.println("-------------------------------------");
        colleague2.doSelfMethod();
        System.out.println("-------------------------------------");
        colleague2.doDepMethod();
        System.out.println("-------------------------------------");

    }

}

Output result:

-------------------------------------
ConcreteColleague1----doSelfMethod()
-------------------------------------
ConcreteColleague1----doDepMethod()
ConcreteMediator----doSomething1()
ConcreteColleague1----doSelfMethod()
ConcreteColleague2----doSelfMethod()
-------------------------------------
ConcreteColleague2----doSelfMethod()
-------------------------------------
ConcreteColleague2----doDepMethod()
ConcreteMediator----doSomething2()
ConcreteColleague1----doSelfMethod()
ConcreteColleague2----doSelfMethod()
-------------------------------------

Intermediary mode - airport dispatching aircraft

UML diagram

concrete example

Abstract class—airplane Fly:

public abstract class Fly {
    //Defines whether the aircraft is inbound or outbound
    public static String typeIn = "IN";
    public static String typeOUT = "OUT";

    protected String name;
    protected int id;
    //Definition Mediator Airport Dispatch Center
    protected AirportMediator airportMediator;

    public Fly(String name, int id) {
        super();
        this.name = name;
        this.id = id;
    }

    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }

    public AirportMediator getAirportMediator() {
        return airportMediator;
    }

    public void setAirportMediator(AirportMediator airportMediator) {
        this.airportMediator = airportMediator;
    }
    //Define the aircraft to perform its own operations
    public abstract void doSelfMethod(String type);
    //Define aircraft execution and airport dispatch center operations
    public abstract void doDepMethod(String type);
    //Define Aircraft Inbound Operations
    public abstract void in();
    //Define aircraft outbound operations
    public abstract void out();
    //Define the aircraft to listen to the notification of the airport control center
    public abstract void listerMediatorNotification(String notification);

}

Specific aircraft category—ConcreteFly:

public class ConcreteFly extends Fly {

    public ConcreteFly(String name, int id) {
        super(name, id);
        // TODO Auto-generated constructor stub
    }

    @Override
    public void doSelfMethod(String type) {
        // TODO Auto-generated method stub
        System.out.println("ConcreteFly---doSelfMethod");
        System.out.println("Fly:"+ super.name +"---"+type.toLowerCase());       
    }

    @Override
    public void doDepMethod(String type) {
        // TODO Auto-generated method stub
        System.out.println("ConcreteFly---doDepMethod");
        System.out.println("Fly:"+ super.name +"-------doDepMethod()");
        super.airportMediator.doManager(this,type);

    }

    @Override
    public void in() {
        // TODO Auto-generated method stub
        System.out.println("ConcreteFly---in()---Fly:"+ super.name +"-------in");
        doSelfMethod(typeIn);
        doDepMethod(typeIn);
    }

    @Override
    public void out() {
        // TODO Auto-generated method stub
        System.out.println("ConcreteFly---out()---Fly:"+ super.name +"-------out");
        doSelfMethod(typeOUT);
        doDepMethod(typeOUT);
    }


    @Override
    public void listerMediatorNotification(String notification) {
        // TODO Auto-generated method stub
        System.out.println("ConcreteFly----listerMediatorNotification");
        System.out.println("Fly:"+super.name + "--lister Mediator Notification:"+notification);
    }

}

Mediator role—AirportMediator:

import java.util.ArrayList;


public class AirportMediator {
    //All aircraft at this airport
    private ArrayList<Fly> array = new ArrayList<Fly>();

    public void add(ConcreteFly fly){
        array.add(fly);
    }

    public void remove(ConcreteFly fly){
        array.remove(fly);
    }
    //Execute dispatch commands
    public void doManager(Fly fly,String type){
        System.out.println("AirportMediator---doManager");

        if(type.equals(Fly.typeIn)){
            if(!array.contains(fly)){
                array.add(fly);
            }
        }else if (type.equals(Fly.typeOUT)) {
            if(array.contains(fly)){
                array.remove(fly);
            }
        }

        for(int i=0;i<array.size();i++){            
            ((ConcreteFly)array.get(i)).listerMediatorNotification("Mediator Notifycation:Fly:"+fly.getName()
                    +"---"+type.toLowerCase()+"---Individual aircraft are dispatched on command");
        }

    }

}

Client:

public class Client {


    public static void main(String[] args) {
        // TODO Auto-generated method stub
        AirportMediator airportMediator = new AirportMediator();

        ConcreteFly f1 = new ConcreteFly("0001", 1);
        ConcreteFly f2 = new ConcreteFly("0002", 2);
        ConcreteFly f3 = new ConcreteFly("0003", 3);

        f1.setAirportMediator(airportMediator);
        f2.setAirportMediator(airportMediator);
        f3.setAirportMediator(airportMediator);

        f1.in();
        System.out.println("---------------------------------------");
        f2.in();
        System.out.println("---------------------------------------");
        f3.in();
        System.out.println("---------------------------------------");
        f1.out();
        System.out.println("---------------------------------------");
        f2.out();
        System.out.println("---------------------------------------");
        f3.out();
        System.out.println("---------------------------------------");  
    }
}

Output result:

ConcreteFly---in()---Fly:0001-------in
ConcreteFly---doSelfMethod
Fly:0001---in
ConcreteFly---doDepMethod
Fly:0001-------doDepMethod()
AirportMediator---doManager
ConcreteFly----listerMediatorNotification
Fly:0001--lister Mediator Notification:Mediator Notifycation:Fly:0001---in---Individual aircraft are dispatched on command
---------------------------------------
ConcreteFly---in()---Fly:0002-------in
ConcreteFly---doSelfMethod
Fly:0002---in
ConcreteFly---doDepMethod
Fly:0002-------doDepMethod()
AirportMediator---doManager
ConcreteFly----listerMediatorNotification
Fly:0001--lister Mediator Notification:Mediator Notifycation:Fly:0002---in---Individual aircraft are dispatched on command
ConcreteFly----listerMediatorNotification
Fly:0002--lister Mediator Notification:Mediator Notifycation:Fly:0002---in---Individual aircraft are dispatched on command
---------------------------------------
ConcreteFly---in()---Fly:0003-------in
ConcreteFly---doSelfMethod
Fly:0003---in
ConcreteFly---doDepMethod
Fly:0003-------doDepMethod()
AirportMediator---doManager
ConcreteFly----listerMediatorNotification
Fly:0001--lister Mediator Notification:Mediator Notifycation:Fly:0003---in---Individual aircraft are dispatched on command
ConcreteFly----listerMediatorNotification
Fly:0002--lister Mediator Notification:Mediator Notifycation:Fly:0003---in---Individual aircraft are dispatched on command
ConcreteFly----listerMediatorNotification
Fly:0003--lister Mediator Notification:Mediator Notifycation:Fly:0003---in---Individual aircraft are dispatched on command
---------------------------------------
ConcreteFly---out()---Fly:0001-------out
ConcreteFly---doSelfMethod
Fly:0001---out
ConcreteFly---doDepMethod
Fly:0001-------doDepMethod()
AirportMediator---doManager
ConcreteFly----listerMediatorNotification
Fly:0002--lister Mediator Notification:Mediator Notifycation:Fly:0001---out---Individual aircraft are dispatched on command
ConcreteFly----listerMediatorNotification
Fly:0003--lister Mediator Notification:Mediator Notifycation:Fly:0001---out---Individual aircraft are dispatched on command
---------------------------------------
ConcreteFly---out()---Fly:0002-------out
ConcreteFly---doSelfMethod
Fly:0002---out
ConcreteFly---doDepMethod
Fly:0002-------doDepMethod()
AirportMediator---doManager
ConcreteFly----listerMediatorNotification
Fly:0003--lister Mediator Notification:Mediator Notifycation:Fly:0002---out---Individual aircraft are dispatched on command
---------------------------------------
ConcreteFly---out()---Fly:0003-------out
ConcreteFly---doSelfMethod
Fly:0003---out
ConcreteFly---doDepMethod
Fly:0003-------doDepMethod()
AirportMediator---doManager
---------------------------------------

advantage

The advantage of the intermediary model is to reduce the dependence between classes, and change the original one-to-many dependence into one-to-one dependence. Colleague classes only rely on the intermediary, which reduces the dependence of classes, and of course reduces the inter-class dependency. coupling.

shortcoming

The intermediary will expand greatly, and the logic is complex. The original direct interdependence of N objects is converted into the intermediary and colleague class dependencies. The more colleague classes, the more complex the intermediary's logic.

Pattern implementation in Android source code

android Mediator sample:—KeyguardViewMediator

uml diagram:

key code:

Colleague role:
KeyguardService:

./base/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java
public class KeyguardService extends Service {
    //mediator role
    private KeyguardViewMediator mKeyguardViewMediator;

    @Override
    public void onCreate() {
        ((SystemUIApplication) getApplication()).startServicesIfNeeded();
        //Intermediary role initialization
        mKeyguardViewMediator =
                ((SystemUIApplication) getApplication()).getComponent(KeyguardViewMediator.class);
    }

    private final IKeyguardService.Stub mBinder = new IKeyguardService.Stub() {

        @Override // Binder interface
        public void addStateMonitorCallback(IKeyguardStateCallback callback) {
            checkPermission();
            //Invoke the mediator role
            mKeyguardViewMediator.addStateMonitorCallback(callback);
        }

        @Override // Binder interface
        public void verifyUnlock(IKeyguardExitCallback callback) {
            checkPermission();
            //Invoke the mediator role
            mKeyguardViewMediator.verifyUnlock(callback);
        }
        ......
        @Override
        public void onActivityDrawn() {
            checkPermission();
            //Invoke the mediator role
            mKeyguardViewMediator.onActivityDrawn();
        }
    };

}

Colleague role:
FingerprintUnlockController:

./base/packages/SystemUI/src/com/android/systemui/statusbar/phone/FingerprintUnlockController.java
public class FingerprintUnlockController extends KeyguardUpdateMonitorCallback {
  //mediator role
  private KeyguardViewMediator mKeyguardViewMediator;
    @Override
    public void onFingerprintAuthenticated(int userId) {
        ......       
        switch (mMode) {
            ...... 
            case MODE_WAKE_AND_UNLOCK:
                ...... 
                //Invoke actor pattern
                mKeyguardViewMediator.onWakeAndUnlocking();
                ...... 
    }
}

Mediator: KeyguardViewMediator

framework/base/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java

The KeyguardViewMediator class acts as a mediator to coordinate the communication of various roles.

References

(1). Zen of Design Patterns—Chapter 14 Intermediary Pattern
(2) Intermediary mode
https://github.com/simple-android-framework/android_design_patterns_analysis/tree/master/mediator

Tags: Design Pattern Android

Posted by alpha2zee on Tue, 24 Jan 2023 04:28:58 +1030