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