introduce

Mediator Pattern is also called Mediator Pattern or Mediator Pattern. Mediator itself means both Mediator and Mediator. In everyday life, the role of mediator or mediator is one we often see as “peacemaker”, that is, the role of reconciling two people in a dispute.

define

The mediator pattern wraps up a set of ways in which objects interact so that they don’t have to obviously interact with each other. So that they can be loosely coupled. When the functions of some objects are changed, the functions of other objects are not affected immediately. These functions can be changed independently of each other. The mediator pattern transforms many-to-many interactions into one-to-many interactions. The mediator pattern abstracts the behavior and collaboration of objects and treats the interaction of objects at small scales separately from other objects.

Usage scenarios

When there are many interaction operations between objects and the behavior operations of each object depend on each other, the mediator pattern can be used to solve the tight coupling problem in order to prevent the modification of the behavior of one object from involving the modification of the behavior of many other objects. The pattern changes the many-to-many relationship between objects into one-to-many relationship, and the mediator object changes the system from network structure to mediator-centered star structure, which can reduce the complexity of the system and improve the scalability.

UML class diagrams

  • Mediator: An abstract Mediator role that defines the interface between peer objects and Mediator objects. It is generally implemented as an abstract class.
  • ConcreteMediator: ConcreteMediator role, inherited from abstract mediator, that implements methods defined by the parent class that receive messages and issue commands to concrete colleague objects.
  • Colleague: An abstract Colleague class role that defines an interface to a mediator object that is aware only of the mediator and not of other Colleague objects.
  • ConcreteColleagueA/B: specific colleague class, inheritance colleagues on abstract classes, each class specific colleagues know itself on a small scale, and don’t know the purpose of it on a larger scale.

Code sample

A simple example

Mediation abstract class:

public abstract class Mediator {
    /** * A */
    protected ConcreteColleagueA concreteColleagueA;

    /** * Class B */
    protected ConcreteColleagueB concreteColleagueB;

    /** * abstract mediation method, subclass implementation */
    public abstract void  method(a);

    public void setConcreteColleagueA(ConcreteColleagueA concreteColleagueA){
        this.concreteColleagueA = concreteColleagueA;
    }

    public void setConcreteColleagueA(ConcreteColleagueB concreteColleagueB){
        this.concreteColleagueB = concreteColleagueB; }}Copy the code

Specific intermediary:

public class ConcreteMediator extends Mediator {
    @Override
    public void method(a) { concreteColleagueA.action(); concreteColleagueB.action(); }}Copy the code

Abstract colleagues:

public abstract class Colleague {
    /** * the intermediary object */
    protected Mediator mediator;

    /** * Peer role specific behavior, implemented by subclasses */
    public abstract void  action(a);

    public Colleague(Mediator mediator) {
        this.mediator = mediator; }}Copy the code

The concrete colleague implements class A/B

public class ConcreteColleagueA extends Colleague {
    public ConcreteColleagueA(Mediator mediator) {
        super(mediator);
    }

    @Override
    public void action(a) {
        System.out.println("ConcreteColleagueA submits information to intermediaries for processing."); }}Copy the code
public class ConcreteColleagueB extends Colleague {
    public ConcreteColleagueB(Mediator mediator) {
        super(mediator);
    }

    public void action(a) {
        System.out.println("ConcreteColleagueB submits information to an intermediary for processing."); }}Copy the code

test

    @Test
    public void testMediator(a){
        ConcreteMediator mediator = new ConcreteMediator();
        mediator.setConcreteColleagueA(new ConcreteColleagueA(mediator));
        mediator.setConcreteColleagueB(new ConcreteColleagueB(mediator));
        mediator.method();
    }
Copy the code

output

ConcreteColleagueA submits the information to the intermediary for processingCopy the code

In actual combat

Requirements: use code to demonstrate how the motherboard in the computer CPU, memory, graphics card, IO equipment together, and control their playback audio and video data? Use the broker model

Abstract mediation classes:

public abstract class Mediator {

    /** * A way to notify mediators when peer objects change * the mediator notifies other peer objects when peer objects change */
    public abstract void changed(Colleague c);
}
Copy the code

Concrete abstract mediation classes:

public class MainBoard extends Mediator {

    /**
     * 光驱设备
     */
    private CDDevice cdDevice;
    /** * CPU */
    private CPU cpu;
    /** ** Sound card device */
    private SoundCard soundCard;
    /**
     * 光驱设备
     */
    private GraphicsCard graphicsCard;


    @Override
    public void changed(Colleague c) {
        // If the cd-rom drive reads the data
        if (c == cdDevice){
            handleCD((CDDevice)c);
        }

        // If the CPU is finished processing the data
        if(c == cpu){ handleCPU((CPU)c); }}/** * Handles the CPU's interaction with other devices after reading data *@param cpu
     */
    private void handleCPU(CPU cpu) {
        this.soundCard.soundPlay(cpu.getDataSound());
        this.graphicsCard.videoPlay(cpu.getDataVideo());


    }

    /** * Handles the interaction between the drive and other devices after reading data *@param cdDevice
     */
    private void handleCD(CDDevice cdDevice) {
        this.cpu.decodeData(cdDevice.read());
    }


    /** * set the CPU */
    public  void  setCPU(CPU cpu){
        this.cpu = cpu;
    }

    /** * set CD */
    public void  setCdDevice(CDDevice cdDevice){
        this.cdDevice = cdDevice;
    }

    /** * set the sound card */
    public void setSoundCard(SoundCard soundCard){
        this.soundCard = soundCard;
    }

    /** * Sets the graphics card */
    public void setGraphicsCard(GraphicsCard graphicsCard){
        this.graphicsCard = graphicsCard; }}Copy the code

Abstract colleagues:

public class CDDevice extends Colleague {
    private String videoData;// Video data
    public CDDevice(Mediator mediator) {
        super(mediator);
    }

    /** * Read the video data *@return* /
    public String read(a){
        return videoData;
    }

    /** * Load video data */
    public void load(a){
        videoData = "Video data, audio data";
        mediator.changed(this); }}Copy the code

CPU, GraphicsCard,SoundCard, all of these implementations are pretty much out of code.

Operation:

    @Test
    public void testMediator2(a){

        // Construct motherboard objects -- that is, intermediaries
        MainBoard mainBoard = new MainBoard();
        // Construct parts separately
        CPU cpu = new CPU(mainBoard);

        CDDevice cdDevice = new CDDevice(mainBoard);

        GraphicsCard graphicsCard = new GraphicsCard(mainBoard);

        SoundCard soundCard = new SoundCard(mainBoard);

        // Install the components on the motherboard
        mainBoard.setCdDevice(cdDevice);
        mainBoard.setCPU(cpu);
        mainBoard.setGraphicsCard(graphicsCard);
        mainBoard.setSoundCard(soundCard);

        // After the installation is complete, start playing the video.
        cdDevice.load();


    }
Copy the code

output:

Audio = [Audio data] Video = [Video data]Copy the code

We can understand from the above program demonstration, intermediary mode is used to coordinate the interaction between multiple objects, just like the motherboard in the above example, if there is no motherboard intermediary, then no part of the computer should be associated with other parts, For example, the CPU must interact with memory, CPU must interact with graphics card, CPU must interact with IO device, etc., which will form a complex network graph, and the emergence of the intermediary pattern is to program this complex network graph into a clear structure of the star chart, with the intermediary in the center.

conclusion

In object-oriented programming language, a class will inevitably produce dependencies and other classes, if the dependencies as intricate as mesh, so will inevitably affect our code execution efficiency, the use of appropriate mediator pattern can be in this kind of dependencies decoupling makes clear logical structure, however, if several dependencies between classes is not complicated, Using the mediator pattern complicates an otherwise uncomplicated logical structure, so consider the pros and cons before deciding to use the mediator pattern.

Article code address

Special thanks to

Android source code design pattern analysis and combat

Thank you for reading, thank you!