תבנית העיצוב של תיאום היא אחת מתבניות העיצוב ההתנהגותיות, ולכן היא מתעסקת בהתנהגויות של אובייקטים. תבנית העיצוב של תיאום משמשת לספק תושבת תקשורת מרכזית בין אובייקטים שונים במערכת.
תבנית עיצוב של תיאום
על פי GoF, מטרת תבנית עיצוב תיאום היא:
לאפשר שביל חיבור חריג על ידי טמיעת הדרך בה אובייקטים שונים מתקשרים ומתחילים זה עם זה. מאפשר לפעולות של כל אובייקט להשתנות באופן תלת-מימדי זה מזה.
התבנית של עיצוב המתווך עוזרת מאוד ביישומים ארגוניים בהם מספר אובייקטים מתקשרים עם יחד עם הם. אם האובייקטים מתקשרים ישירות זה עם זה, רכיבי המערכת קשורים בחוזים יבשים זה את זה, מה שגורם לעלות תחזוקה גבוהה יותר וקשה להרחיב. תבנית המתווך מתמקדת בספק מתווך בין אובייקטים לתקשורת ועוזרת ביישום התמונגות לא יבשה בין אובייקטים. סוחר התעופה הוא דוגמה נהדרת לתבנית מתווך בה חדר בקרת השדה פועל כמתווך לתקשורת בין טיסות שונות. המתווך פועל כמנתב בין האובייקטים ויכול להיות לו היגיון עצמאי לספק אמצעי תקשורת. אובייקטי המערכת המתקשרים זה עם זה נקראים עמיתים. כללית אנו יש לנו ממשק או מחלקה אבסטרקטית המספקת את החוזה לתקשורת ולאחר מכן יש לנו מימוש ממשקי המתווכים הממוקמים בסיסי המערכת. עבור הדוגמה שלנו, אנו ננסה לממש יישום של יישום צ'אט בו משתמשים יכולים להיכנס לצ'אט קבוצתי. כל משתמש יזוהה על ידי השם שלו והם יכולים לשלוח ולקבל הודעות. ההודעה שנשלחת על ידי כל משתמש צריכה להתקבל על ידי כל המשתמשים האחרים בקבוצה.
ממשק תבנית מתווך
לפני הכל ניצור ממשק מתווך המגדיר את החוזה למתווכים הספציפיים. ChatMediator.java
package com.journaldev.design.mediator;
public interface ChatMediator {
public void sendMessage(String msg, User user);
void addUser(User user);
}
תבנית התיים פניות מממשק עמית
משתמשים יכולים לשלוח ולקבל הודעות, ולכן ניתן ליצור ממשק משתמש או מחלקה אבסטרקטית. אני יוצר את המשתמש כמחלקה אבסטרקטית כמו שמוצג למטה. User.java
package com.journaldev.design.mediator;
public abstract class User {
protected ChatMediator mediator;
protected String name;
public User(ChatMediator med, String name){
this.mediator=med;
this.name=name;
}
public abstract void send(String msg);
public abstract void receive(String msg);
}
שים לב שיש ל-Mediator התייחסות לאובייקט, זה דרוש לתקשורת בין משתמשים שונים.
התייחסות ממשק
כעת ניצור מחלקת מתייחסת ממשק ממשים, אשר תכיל רשימה של משתמשים בקבוצה ותספק לוגיקה לתקשורת ביניהם. ChatMediatorImpl.java
package com.journaldev.design.mediator;
import java.util.ArrayList;
import java.util.List;
public class ChatMediatorImpl implements ChatMediator {
private List users;
public ChatMediatorImpl(){
this.users=new ArrayList<>();
}
@Override
public void addUser(User user){
this.users.add(user);
}
@Override
public void sendMessage(String msg, User user) {
for(User u : this.users){
//הודעה לא צריכה להתקבל על ידי המשתמש ששולח אותה
if(u != user){
u.receive(msg);
}
}
}
}
התייצבות מערכת התייחסות תבנית ממשק עמית
כעת ניתן ליצור קבוצת מחלקות משתמש ספציפיות לשימוש במערכת הלקוח. UserImpl.java
package com.journaldev.design.mediator;
public class UserImpl extends User {
public UserImpl(ChatMediator med, String name) {
super(med, name);
}
@Override
public void send(String msg){
System.out.println(this.name+": Sending Message="+msg);
mediator.sendMessage(msg, this);
}
@Override
public void receive(String msg) {
System.out.println(this.name+": Received Message:"+msg);
}
}
שים לב ששיטת ה-send() משתמשת בתייחסות למדיאטור כדי לשלוח את ההודעה למשתמשים ואין לה מושג כיצד היא תוכנס לטיפול של התייחסות המדיאטור.
דוגמה לתכנית לקוח של דוגמא לתבנית הברובר
בואו לבדוק את יישום הצ'אט שלנו עם תכנית פשוטה בה ניצור גורם ונוסיף משתמשים לקבוצה, ואחד מהמשתמשים ישלח הודעה. ChatClient.java
package com.journaldev.design.mediator;
public class ChatClient {
public static void main(String[] args) {
ChatMediator mediator = new ChatMediatorImpl();
User user1 = new UserImpl(mediator, "Pankaj");
User user2 = new UserImpl(mediator, "Lisa");
User user3 = new UserImpl(mediator, "Saurabh");
User user4 = new UserImpl(mediator, "David");
mediator.addUser(user1);
mediator.addUser(user2);
mediator.addUser(user3);
mediator.addUser(user4);
user1.send("Hi All");
}
}
שימו לב שהתוכנית הלקוח היא פשוטה מאוד ואין לה מושג כיצד ההודעה נעזרת ואם הגורם מקבל משתמש או לא. פלט של דוגמא לתבנית הברובר הוא:
Pankaj: Sending Message=Hi All
Lisa: Received Message:Hi All
Saurabh: Received Message:Hi All
David: Received Message:Hi All
תרשים כיתה של דוגמא לתבנית הברובר
דוגמא לתבנית הברובר ב-JDK
- מחלקת java.util.Timer scheduleXXX() methods
- ממשק המרץ של Java Concurrency Executor execute() method.
- מתודת invoke() של java.lang.reflect.Method.
נקודות חשובות בתבנית עיצוב המתווך
- תבנית המתווך שימושית כאשר הלוגיקה של התקשורת בין אובייקטים היא מורכבת, נוכל להשתמש בנקודת מרכז של תקשורת שמטפלת בלוגיקת התקשורת.
- שירות ההודעות של ג'אווה (JMS) משתמש בתבנית המתווך ביחד עם תבנית העקבוב כדי לאפשר ליישומים להירשם ולפרסם נתונים ליישומים אחרים.
- אנו לא צריכים להשתמש בתבנית המתווך רק כדי להשיג התממות פריקה, מכיוון שאם מספר המתווכים יגדל, אז יהיה קשה לתחזק אותם.
זהו הכל לתבנית עיצוב המתווך וליישום שלה בג'אווה.
Source:
https://www.digitalocean.com/community/tutorials/mediator-design-pattern-java