Abstract: This paper describes the mediator pattern in Gof 23 design pattern with an example scenario, and implements it with Quarkus program code. At the same time, it also gives the UML model of the implementation code.
Key words: Gof 23 design pattern mediator pattern Quarkus
1 basic knowledge
1.1 standard definition
The standard definition of Mediator pattern: a mediation object is used to encapsulate a series of object interactions. The Mediator makes the objects do not need to explicitly refer to each other, so that they are loosely coupled, and the interaction between them can be changed independently.
1.2 analysis and description
Mediator Mediator mode, also known as mediator mode, belongs to object behavior mode. Mediator mode packages a series of ways in which objects interact, so that these objects do not have to interact obviously, so that they can be loosely coupled. When the interaction between some objects changes, it will not immediately affect the interaction between other objects. Ensure that these interactions can Independent changes. The mediator pattern transforms many to many interaction into one to many interaction, and encapsulates the complex relationship between classes into a mediator class. The mediator model abstracts the behavior and cooperation of objects, and processes the interaction between objects and other objects on a small scale.
The Mediator pattern structure is shown in Figure 1. Its roles include abstract Mediator role, Concrete Mediator role, abstract Colleague role and Concrete Colleague role.
Figure 1 mediator mode structure
Abstract Mediator role: define the interface from colleague object to Mediator object, in which the main method is one (or more) event methods. In some cases, this abstract object can be omitted. Generally speaking, this role is implemented by an abstract class or interface.
Concrete Mediator role: it inherits from the abstract mediator and implements the event methods declared by the abstract superclass. The Concrete Mediator knows all the specific colleague classes. It receives messages from the specific colleague object and sends commands to the specific colleague object. Generally speaking, this role is implemented by a specific class.
Abstract Colleague role: defines the interface from the mediator to the Colleague object. The Colleague object only knows the mediator and does not know the other Colleague objects. Generally speaking, this role is implemented by an abstract class or object.
Concrete Colleague role: all Concrete Colleague classes are inherited from abstract colleague classes. Each Concrete Colleague class knows its behavior in a small range, but does not know its purpose in a large range. In the schematic class diagram, the Concrete Colleague classes are Colleague1 and Colleague2. Generally speaking, this role is implemented by a concrete class.
2. Application scenario examples
For example, the company has many projects, including project work and project personnel. But sometimes, there are too many project personnel and too few project personnel. Some projects have a large workload and some projects have a small workload, which requires the technical director to act as the coordinator, transfer the personnel of some projects to other projects, or arrange the work of some projects to other projects. The rules do not allow self adjustment between project managers, but must be mediated by the technical director, which is the mediator mode. The use case diagram is shown in Figure 2.
Figure 2 mediator mode use case diagram
Here, the Mediator abstract class can be understood as the abstract Mediator role. The TechnicalDirector class can be understood as the Concrete Mediator role. The AbstractProject abstract class can be understood as the abstract Colleague role. ProjectA and ProjectB are Concrete Colleague classes (concrete collide) role. Its implementation class diagram is shown in Figure 3. The TechnicalDirector class inherits the Mediator abstract class on the one hand and is associated with the AbstractProject abstract class on the other. ProjectA and ProjectB inherit the AbstractProject abstract class and are associated with the TechnicalDirector class at the same time.
Figure 3 class diagram of mediator mode
The implementation sequence of mediator mode is shown in Figure 4. The implementation sequence is described as follows: ① create a leader object based on the TechnicalDirector class; ② Create a projecta object based on the projecta class; ③ Create a projectb object based on the projectb class; ④ Call the setProjectA method of the leader object to assign the projecta object to the leader object. ⑤ Call the setProjectB method of the leader object to assign the projectb object to the leader object. ⑥ Call the leader object changemember method to realize the personnel transfer of projecta object and projectb object; ⑦ Call the leader object changetask method to realize the task transfer of projecta object and projectb object; ⑧ Call the showProjectContent method of projecta object to display the internal personnel and tasks of projecta; ⑨ Call the showProjectContent method of projectb object to display the internal personnel and tasks of projectb;
Figure 4 implementation sequence of mediator mode
The leader object is a mediator. The personnel and task exchange and coordination within projectA object and projectB object are realized through the method of the leader object.
3. Implementation program code of Quarkus
Quarkus program implementation mainly includes seven files: AbstractProject abstract class file, Mediator abstract class file, TechnicalDirector class file, ProjectA class file, ProjectB class file, Member class file and Task class file. The relationship is shown in Figure 3. The program codes of these seven files are listed below. Finally, the test codes are listed and the output results are displayed.
The AbstractProject abstract class program code is shown in listing 01.
Program code list 01
public abstract class { protected String projectName ; protected TechnicalDirector leader; protected Map<String,Member> memberMap = new HashMap<String,Member>(); protected Map<String,Task> taskMap = new HashMap<String,Task>(); protected void initizeTask(Map<String,Task> map){taskMap = map;} protected void initizeMember(Map<String,Member> map){memberMap = map;} public void addMember(Member member){memberMap.put(member.getMemberName(), member);} public void removeMember(Member member){memberMap.remove(member.getMemberName()); } public void addTask(Task task){taskMap.put(task.getTaskName(), task);} public void reduceTask(Task task){taskMap.remove(task.getTaskName()); } public String getProjectName() {return projectName;} public void setProjectName(String projectName) {this.projectName = projectName; } public TechnicalDirector getLeader() {return leader; } public void setLeader(TechnicalDirector leader) { this.leader = leader;} public void showProjectContent(){ System.out.println("display"+getProjectName()+"Project members and tasks:"); System.out.print("Project members:"); String memberName; Iterator it = memberMap.keySet().iterator(); while (it.hasNext()){ memberName = (String)it.next(); System.out.print(memberName+";"); } System.out.println(); String taskName; System.out.print("Project tasks:"); it = taskMap.keySet().iterator(); while (it.hasNext()){ taskName = (String)it.next(); System.out.print(taskName+";"); } System.out.println(); } }
The Mediator abstract class program code is shown in listing 02.
Program code list 02
public abstract class Mediator { public void changMember(AbstractProject project1,AbstractProject project2,Member member){ project1.removeMember(member); project2.addMember(member); } public void changTask(AbstractProject project1,AbstractProject project2,Task task){ project1.reduceTask(task); project2.addTask(task); } public void doCoordination(){} }
TechnicalDirector inherits the Mediator abstract class, and its program code is shown in listing 03.
Program code list 03
@ApplicationScoped public class TechnicalDirector extends Mediator { private ProjectA projectA; private ProjectB projectB; private String directorName; public TechnicalDirector(){} public String getDirectorName() { return directorName; } public void setDirectorName(String directorName) { this.directorName = directorName; } public ProjectA getProjectA() { return projectA; } public void setProjectA(ProjectA projectA) { this.projectA = projectA; } public ProjectB getProjectB() { return projectB; } public void setProjectB(ProjectB projectB) { this.projectB = projectB; } public void doCoordination() { } }
ProjectA class and ProjectB class inherit AbstractProject abstract class, and their program code is shown in listing 04.
Program code list 04
@ApplicationScoped public class ProjectA extends AbstractProject{ public ProjectA(){ projectName = "ProjectA"; } public ProjectA(Map<String,Member> members,Map<String,Task> tasks){ initizeMember(members); initizeTask(tasks); projectName = "ProjectA"; } public ProjectA setMembers(Map<String,Member> members){ initizeMember(members); return this; } public ProjectA setTasks(Map<String,Task> tasks){ initizeTask(tasks); return this; } } @ApplicationScoped public class ProjectB extends AbstractProject { public ProjectB(){ projectName = "ProjectB"; } public ProjectB(Map<String, Member> members, Map<String, Task> tasks) { initizeMember(members); initizeTask(tasks); projectName = "ProjectB"; } public ProjectB setMembers(Map<String,Member> members){ initizeMember(members); return this; } public ProjectB setTasks(Map<String,Task> tasks){ initizeTask(tasks); return this; } }
The program code of Member class and Task class is shown in listing 05.
Program code listing 05
@Dependent public class Member { private String memberName ; public Member(){} public Member(String name){ setMemberName(name); } public String getMemberName() { return memberName; } public void setMemberName(String memberName) { this.memberName = memberName; } } @Dependent public class Task { private String taskName ; public Task(){} public Task(String name){ setTaskName(name); } public String getTaskName() { return taskName; } public void setTaskName(String taskName) { this.taskName = taskName; } }
The code list 06 of the mediator mode test program is as follows:
Program code listing 06
public class MediatorClient implements QuarkusApplication { @ConfigProperty(name = "gof23.behavioralpattern.mediator.title", defaultValue = "gof23") String title; @Inject Member Programmer1,Programmer2,Designer1,Designer2; @Inject Task ProgramTask1,ProgramTask2,DesignTask1,DesignTask2; @Inject ProjectA projectA; @Inject ProjectB projectB; @Inject TechnicalDirector leader ; @Override public int run(String... args) { System.out.println("----" + title + "Presentation output -————————"); // Initialize project personnel and task information Programmer1.setMemberName("Programmer 1"); Programmer2.setMemberName("Programmer 2"); Designer1.setMemberName("Designer 1"); Designer2.setMemberName("Designer 2"); ProgramTask1.setTaskName("Programming work 1"); ProgramTask2.setTaskName("Programming work 2"); DesignTask1.setTaskName("Design work 1"); DesignTask2.setTaskName("Design work 2"); Map<String, Member> ProgrammerMap = new HashMap<String, Member>(); ProgrammerMap.put(Programmer1.getMemberName(), Programmer1); ProgrammerMap.put(Programmer2.getMemberName(), Programmer2); Map<String, Member> DesignerMap = new HashMap<String, Member>(); DesignerMap.put(Designer1.getMemberName(), Designer1); DesignerMap.put(Designer2.getMemberName(), Designer2); Map<String, Task> ProgramTaskMap = new HashMap<String, Task>(); ProgramTaskMap.put(ProgramTask1.getTaskName(), ProgramTask1); ProgramTaskMap.put(ProgramTask2.getTaskName(), ProgramTask2); Map<String, Task> DesignTaskMap = new HashMap<String, Task>(); DesignTaskMap.put(DesignTask1.getTaskName(), DesignTask1); DesignTaskMap.put(DesignTask2.getTaskName(), DesignTask2); projectA.setMembers(ProgrammerMap).setTasks(ProgramTaskMap); projectB.setMembers(DesignerMap).setTasks(DesignTaskMap); // Coordinate project personnel and work System.out.println("----—Pre coordination -————————"); projectA.showProjectContent(); projectB.showProjectContent(); leader.setProjectA(projectA); leader.setProjectB(projectB); // Personnel coordinating the two projects leader.changMember(projectA, projectB, Programmer1); leader.changMember(projectB, projectA, Designer1); // Coordinate the tasks of the two projects leader.changTask(projectA, projectB, ProgramTask1); leader.changTask(projectB, projectA, DesignTask1); System.out.println("----—After coordination -————————"); projectA.showProjectContent(); projectB.showProjectContent(); return 0; } public static void main(String... args) { Quarkus.run(MediatorClient.class, args); } }
The output results of mediator mode test class are as follows:
————————- pre coordination -————————
Display ProjectA project members and tasks:
Project member: programmer 2; Programmer 1;
Project task: programming work 1; Programming work 2;
Display ProjectB project members and tasks:
Project member: Designer 1; Designer 2;
Project task: design work 2; Design work 1;
————————- after coordination -————————
Display ProjectA project members and tasks:
Project member: Designer 1; Programmer 2;
Project task: design work 1; Programming work 2;
Display ProjectB project members and tasks:
Project member: programmer 1; Designer 2;
Project task: design work 2; Programming work 1;
4. Download relevant Quarkus program source code
You can get the code directly from github, and readers can clone the pre prepared sample code from github.
git clone https://github.com/rengang66/quarkus-sample-gof23.git
This is a maven project, and then Maven imports the project. The program is located in the "src\main\java\com\iiit\quarkus\sample\gof23\behavioralpattern\mediator" directory.
At the same time, you can also use the sample code prepared in advance from clone on gitee. The command is as follows:
git clone https://gitee.com/rengang66/quarkus-sample-gof23.git
reference
[1] E.Gamma, R.Helm, R.Johnson, and Vlissides. Design Patterns Elements of Reusable Object Oriented Software. Addison-Wesley, 1995
[2] E.Gamma, R.Helm, R.Johnson, and Vlissides. Design pattern: the basis of reusable object-oriented software, Beijing: Mechanical Industry Press, 2000.9
[3] Yan Hong, Java and pattern, Beijing: Electronic Industry Press two thousand and two point one zero
[4] Wang Junfeng, Qi Xiaobin Design patterns and UML Computer application research, 1999.16 (5), 27-29,39
[5] Chen Qin, Zhu Zhengqiang Application of UML in design pattern description Computer engineering and design, 2003.24 (4), 81-84
[6] Zhou Chuanhong, Wu Sida Extensible PLM customization architecture based on design pattern Manufacturing automation, 2007.29 (4), 27-29,76
[7] Wang Songtao, Wang Lilin Yong Research and improvement of Mediator design pattern Science, technology and engineering, 2005.5 (7), 427-430
[8] Rhoda, Zhang Yuanzhou, Zhou XiaoCong Aspect - oriented implementation of mediator pattern Computer applications and software, 2008.25 (11), 46-47111
[9] He CHENGWAN [1,2,3] he Keqing [1] Tu Wenjie [3] A role implementation method based on Mediator mode Computer engineering, 2006.32 (18), 48-49,94
[10] Ji Chunlei Research on software design pattern and its application Journal of Shanghai Institute of electrical engineering, 2006.9 (5), 46-49,70
[11] Han Peng, Li Chengzhong Design pattern and its application in J2ME Journal of Chengdu Institute of information engineering, 2004.19 (3), 332-335
[12] Zeng Wei, Chen Weibin Application and implementation of design pattern in freshman check - in system Computer technology and development, 2007.17 (7), 178-182
[13] Quarkus official website https://quarkus.io/