3.4. Mediator

3.4.1. تعریف

دیزاین پترن Mediator یک الگوی رفتاری محسوب میشه که جلوی دسترسی مستقیم آبجکت ها به همدیگه رو میگیره و در واقع بین آبجکت ها قرار میگیره تا فقط به واسطه ی Mediator با هم در ارتباط باشن و از Interface واقعی همدیگه مطلع نباشن.

از این طریق میزان Coupling بین آبجکت ها رو بسیار کاهش میده.

3.4.2. چه زمانی استفاده میشه؟

زمانی که در برنامه احساس می کنیم وابستگی یا Coupling زیادی بین اجزا وجود داره این الگو رو به کار میگیریم تا وابستگی رو کاهش بدیم.

یا به عنوان در GUI یا رابط های کاربری گرافیکی که اجزای گرافیکی فرم واسطی هستن برای ارتباط کاربر نهایی با کلاس های برنامه.

3.4.3. اجزاء

الگوی طراحی Mediator از چند بخش اصلی تشکیل میشه:

بخش اول اون Mediator هست که بین بخش های مختلف برنامه قرار میگیره و ارتباط اون ها رو مدیریت می کنه.

و بخش بعد هم Colleague ها هستن که بخش هایی هستن که قصد ارتباط با همدیگه رو دارن.

UML of Chain of Responsibility Design Pattern

Kostyantyn Yuriyovich Kolesnichenko, Public domain, via Wikimedia Commons

Caution

✅ مزایای استفاده

کاهش چشمگیر Coupling و وابستگی بین کلاس ها

ساده سازی ارتباط میان کلاس ها

رعایت اصلی تک مسئولیتی از اصول SOLID و Open/Closed طبق توضیحاتی که داده شد

امکان پیمایش موازی یک Collection به صورت جداگانه

افزایش امکان استفاده مجدد از اجزای برنامه به علت Decouple شدن اجزا

Warning

❌ معایب استفاده

اعمال این الگو در مواردی که واقعا بهش نیاز نیست و Collection های پیچیده ای وجود نداره بسیار اشتباه هست

3.4.4. کاربرد عملی

خب یکی از مهم ترین کاربردهای این الگو در زبان هایی هست که رابط گرافیکی محور یا GUI-Based هستن پس میشه گفت خیلی در PHP کاربرد زیادی نداره اما در مواردی مثل Event dispatcher ها در بسیاری از فریمورک های PHP مورد استفاده قرار میگیره.

خب فرض کنید در حال طراحی یک برنامه پیام رسان در PHP هستیم و قصد پیاده سازی قابلیت چت گروهی رو داریم.

هر گروه میتونه چندین کاربر داشته باشه و کاربر ها میتونن توی گروه پیام ارسال کنن.

بریم ببینیم چطور میشه با این الگو پیادش کرد.

3.4.5. پیاده سازی

قبل از هر چیز Interface مربوط به Mediator رو تعریف می کنیم:

1<?php
2
3interface GroupChatMediatorInterface {
4    public function addUserToGroupChat(User $user, GroupChat $groupChat);
5    public function sendMessageToGroupChat(User $user, GroupChat $groupChat, $message);
6}

در این برنامه کلاس های User و GroupChat همون Colleague ها محسوب میشن که به این صورت اون ها رو تعریف می کنیم:

 1<?php
 2
 3class User
 4{
 5    private string $name;
 6    private $groupChats = [];
 7
 8    public function __construct(string $name)
 9    {
10        $this->name = $name;
11    }
12
13    public function joinGroupChat(GroupChat $groupChat, GroupChatMediatorInterface $mediator): void
14    {
15        // Add user to the group chat via the mediator
16        $mediator->addUserToGroupChat($this, $groupChat);
17        // Add the group chat to the user's list of group chats
18        $this->groupChats[] = $groupChat;
19    }
20
21    public function sendMessageToGroupChat(GroupChat $groupChat, GroupChatMediatorInterface $mediator, $message): void
22    {
23        // Send message to the group chat via the mediator
24        $mediator->sendMessageToGroupChat($this, $groupChat, $message);
25    }
26
27    public function receiveMessage($message): void
28    {
29        // Print out the received message
30        echo "{$this->name} received message: {$message}\n";
31    }
32}
 1<?php
 2
 3class GroupChat
 4{
 5    private string $name;
 6    private array $users = [];
 7
 8    public function __construct($name)
 9    {
10        $this->name = $name;
11    }
12
13    public function addUser(User $user): void
14    {
15        // Add user to the group chat
16        $this->users[] = $user;
17    }
18
19    public function sendMessage(User $user, $message): void
20    {
21        // Send message to all users in the group chat
22        foreach ($this->users as $u) {
23            if ($u !== $user) {
24                $u->receiveMessage($message);
25            }
26        }
27    }
28}

و در نهایت Mediator ما به این صورت پیاده سازی میشه:

 1<?php
 2
 3class GroupChatMediator implements GroupChatMediatorInterface
 4{
 5    public function addUserToGroupChat(User $user, GroupChat $groupChat)
 6    {
 7        // Add user to the group chat
 8        $groupChat->addUser($user);
 9    }
10
11    public function sendMessageToGroupChat(User $user, GroupChat $groupChat, $message)
12    {
13        // Send message to the group chat
14        $groupChat->sendMessage($user, $message);
15    }
16}

3.4.6. نحوه فراخوانی

 1<?php
 2
 3// Create a new mediator
 4$mediator = new GroupChatMediator();
 5
 6// Create some group chats
 7$groupChat1 = new GroupChat("Group Chat 1");
 8$groupChat2 = new GroupChat("Group Chat 2");
 9
10// Create some users
11$user1 = new User("Saleh");
12$user2 = new User("Mina");
13$user3 = new User("Ahmad");
14
15// Add users to group chats
16$user1->joinGroupChat($groupChat1, $mediator);
17$user2->joinGroupChat($groupChat1, $mediator);
18$user2->joinGroupChat($groupChat2, $mediator);
19$user3->joinGroupChat($groupChat2, $mediator);
20
21// Send messages within group chats
22$user1->sendMessageToGroupChat($groupChat1, $mediator, "Hello everyone in Group Chat 1!");
23$user2->sendMessageToGroupChat($groupChat2, $mediator, "Hi all in Group Chat 2!");
24
25// Output:
26// Mina received message: Hello everyone in Group Chat 1!
27// Ahmad received message: Hi all in Group Chat 2!

به همین زیبایی!