Design Patterns - Mediator Pattern (21)

definition

The mediator mode (Mediator), also known as the mediator mode, is a relatively simple mode.

英文: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.

Translation: Encapsulate the interaction of a series of objects (colleagues) with a mediator object. The mediator makes the interaction of each object not required to be explicit, thereby making it loosely coupled, and the mediator can independently change the interaction between them.

Role:

Abstract Mediator role: This role defines the same interface from colleague objects to mediator objects for communication between colleague roles.

Concrete Mediator role: This role implements an abstract mediator, which depends on each colleague role and realizes collaborative behavior by coordinating each colleague role.

Abstract Colleague role: This role defines the interface between the mediator and the colleague object. The colleague object only knows the mediator and does not know the rest of the colleague objects.

Concrete Colleague role: This role implements abstract colleague classes. Each concrete colleague class knows its own behavior in a small range, but does not know its purpose in a large range.

/**
 * Abstract mediator pattern
 */ 
public  abstract  class Mediator {
     // The business logic method of the mediator mode, so that the encapsulated objects do not interact with the display 
    public  abstract  void colleagueChanged(Colleague colleague);
}

/**
 * Specific intermediaries
 */
public class ConcreteMediator extends Mediator{
    private ConcreteColleague1 c1;
    private ConcreteColleague2 c2;

    // The business logic method of the mediator mode, so that the encapsulated object does not need to interact with the display 
    public  void colleagueChanged(Colleague c){
        c1.action();
        c2.action();
    }

    // Factory method to create a colleague object 
    public  void createConcreteMediator(){
        c1 = new ConcreteColleague1(this);
        c2 = new ConcreteColleague2(this);
    }

    // Get the colleague object 
    public ConcreteColleague1 getC1(){
         return c1;
    }
    // Get the colleague object 
    public ConcreteColleague2 getC2(){
         return c2;
    }
}

/**
 * Abstract colleague class
 */
public abstract class Colleague {
    private Mediator mediator;
    //构造函数
    public Colleague(Mediator mediator) {
        this.mediator = mediator;
    }
    // getter and setter methods 
    public Mediator getMediator() {
         return mediator;
    }
    public void setMediator(Mediator mediator) {
        this.mediator = mediator;
    }

    // Abstract action method, implemented by subclasses 
    public  abstract  void action();
     // Business method, call this method to change the internal state of the object 
    public  void change(){
         this .mediator.colleagueChanged( this );
    }

}

/**
 * Specific colleagues class 1
 */
public class ConcreteColleague1 extends Colleague {
    //构造函数
    public ConcreteColleague1(Mediator mediator) {
        super(mediator);
    }

    @Override
    public void action() {
        System.out.println( "This is the action method of colleague 1!" );
    }
}

/**
 * Specific colleague class 2
 */
public class ConcreteColleague2 extends Colleague {
    public ConcreteColleague2(Mediator mediator) {
        super(mediator);
    }

    @Override
    public void action() {
        System.out.println( "This is the method of the concrete colleague class 2!" );
    }
}

source code

advantage 

  • Reduce dependencies between classes. Change the original one-to-many dependencies between classes into one-to-one dependencies, making the relationship between objects easier to understand and maintain.
  • Avoid over-coupling between colleague objects. The colleague class only depends on the mediator, which makes the colleague class easier to reuse, and the mediator class and the colleague class can evolve relatively independently.
  • The mediator pattern abstracts the behavior of objects and the cooperation between objects, and separates the behavior of objects from the interactions of other objects on a small scale.

shortcoming

  • The mediator pattern reduces the complexity of the colleague object, but increases the complexity of the mediator class.
  • The mediator class is often full of relationship coordination code for each concrete colleague class, which is not reusable.

Precautions

The mediator model is simple, but simple does not mean easy to use, it is easy to be misused and abused. In object-oriented programming, there must be dependencies between objects and objects. If a class does not have any dependencies with other classes, then this class is an island, and it is not necessary to exist in the system. It is normal for a class to depend on multiple classes, and it is reasonable to exist, but it is not considered to use the mediator pattern as long as there are multiple dependencies. The mediator pattern is not suitable for use in the following situations:

  • The mediator pattern should not be used when the division of responsibilities is confusing. Often, when a junior designer is unfamiliar with object-oriented techniques, a system can get confused over the separation of responsibilities. The confusion of segregation of responsibilities can create inappropriately complex relationships between objects in the system.
  • The mediator pattern should not be used for data classes and method classes. Junior designers often design a system where a set of classes contain only data, and some classes contain only methods.
  • Correctly understand encapsulation classes. Encapsulation is the behavior first, and the state involved in the behavior second. Behavior and state should not be separated. The mediator pattern is used to manage the interaction of many objects so that these objects can focus on their own behavior.
/**
 * Marriage agency interface
 */ 
public  interface MarriageAgency {
     void pair(Person person);     // Pair for person 
    void register(Person person);     // Register member 
}

/**
 * The class implemented by the intermediary
 */
public class MarriageAgencyImpl implements MarriageAgency{
    List<Man> men = new ArrayList<Man>();   //男会员
    List<Woman> women = new ArrayList<Woman>();   //女会员

    @Override
    public void pair(Person person) {
        if (person.sex == Sex.MALE){
            for (Woman w:women){
                if (w.age == person.requestAge){
                    System.out.println(person.name +" and "+w.name+" are paired successfully!" );
                     return ;
                }
            }
        }else if(person.sex == Sex.FEMALE){
            for (Man m:men){
                if (m.age == person.requestAge){
                    System.out.println(person.name +" and "+m.name+" are paired successfully!" );
                }
            }
        }
        System.out.println( "No suitable candidates found!!!" );
    }

    @Override
    public void register(Person person) {
        if (person.sex == Sex.MALE){
            men.add((Man) person);
        }else if (person.sex == Sex.FEMALE){
            women.add((Woman) person);
        }
    }
}

/**
 * Person abstract class
 */
public abstract class Person {
    String name; // Name 
    int age;   // Age 
    Sex sex;    // Sex

    int requestAge;    // Request the age of the object. For the object 
    Person requestPerson;

    MarriageAgency agency;     // Marriage agency

    public Person(String name, int age, Sex sex, int requestAge, MarriageAgency agency) {
        this.name = name;
        this.age = age;
        this.sex = sex;
        this.requestAge = requestAge;
        this.agency = agency;

        agency.register( this );     // Register a member and register yourself to the agency 
    }

    public  void findPartner(){     // Find the object 
        agency.pair( this );     // Find according to your own data (obj.requestPerson) 
    }
}

/**
 * Gender enumeration
 */
enum  Sex {
    MALE,FEMALE;
}

/**
 * Men's
 */
public class Man extends Person{
    public Man(String name, int age, int requestAge, MarriageAgency agency) {
        super(name, age, Sex.MALE, requestAge, agency);
    }
}

/**
 * women
 */
public class Woman extends Person{
    public Woman(String name, int age, int requestAge, MarriageAgency agency) {
        super(name, age, Sex.FEMALE, requestAge, agency);
    }
}

/**
 * test class
 */
public class Main {
    public static void main(String[] args) {
        MarriageAgency agency = new MarriageAgencyImpl();
         // The name is allen, a 27-year-old man object, looking for a 28-year-old man of the opposite sex
         // agency is an agency, and in the constructor, it will pass the object constructed by itself to the agency 
        Person m1 = new Man ("allen",27,28 ,agency);
        Person m2 = new Man("sywer",25,20,agency);
        Person w1 = new Woman("catalin",28,23,agency);
        Person w2 = new Woman("feilicity",25,23,agency);
        m1.findPartner();    // Call agency.find(this), that is, m1 executes this method to call the find method of the intermediary, with itself as a parameter. 
        m2.findPartner();
    }
}

source code

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324805914&siteId=291194637