نمط تصميم الوسيط هو أحد أنماط التصميم السلوكية، لذا يتعامل مع سلوك الكائنات. يُستخدم نمط تصميم الوسيط لتوفير وسيلة اتصال مركزية بين كائنات مختلفة في النظام.
نمط تصميم الوسيط
وفقًا لـ 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);
}
لاحظ أن لدى المستخدم مرجع إلى كائن الوسيط، فهو مطلوب للتواصل بين مستخدمين مختلفين.
وسيط محدد
الآن سنقوم بإنشاء صنف وسيط محدد، وسيحتوي على قائمة من المستخدمين في المجموعة وسيوفر منطقًا للتواصل بين المستخدمين. 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()
- مدير تنفيذ التعدد في جافا أسلوب execute().
- أسلوب invoke() في فئة java.lang.reflect.Method.
نقاط مهمة لنمط التصميم الوسيط
- نمط الوسيط مفيد عندما تكون منطق التواصل بين الكائنات معقدة، يمكننا أن نمتلك نقطة وسيطة مركزية للتواصل التي تتولى منطق التواصل.
- يستخدم خدمة الرسائل في جافا (JMS) نمط الوسيط جنبًا إلى جنب مع نمط المراقب للسماح للتطبيقات بالاشتراك ونشر البيانات لتطبيقات أخرى.
- لا ينبغي استخدام نمط الوسيط فقط لتحقيق فصل فعال بين الكائنات لأنه إذا زاد عدد الوسطاء، فسيصعب صيانتها.
هذا كل شيء بالنسبة لنمط التصميم الوسيط وتنفيذه في جافا.
Source:
https://www.digitalocean.com/community/tutorials/mediator-design-pattern-java