Mediator Pattern (Arabulucu Tasarım Kalıbı), nesneler arasındaki doğrudan iletişimi kaldırarak, iletişimi merkezi bir nesne üzerinden yönetmeye olanak tanıyan bir davranışsal tasarım desenidir. Bu desen, sınıflar arasındaki bağımlılığı azaltır ve sistemin daha modüler ve esnek olmasını sağlar.
Ne Zaman Kullanılmalıdır?
Mediator Pattern şu durumlarda kullanışlıdır:
- Nesneler arasındaki doğrudan bağımlılığı azaltmak gerektiğinde.
- Bileşenlerin birbirleriyle fazla etkileşim içinde olduğu ve kodun karmaşık hale geldiği durumlarda.
- İstemci kodunun, sistemin iç işleyişine dair fazla bilgiye sahip olmaması gerektiğinde.
- Çok sayıda bileşen arasında iletişim sağlanması gerektiğinde.
Mediator Pattern’in Avantajları ve Dezavantajları
Avantajlar:
- Bağımsız bileşenler oluşturur: Nesneler doğrudan birbirleriyle değil, aracı bir nesne üzerinden haberleşir.
- Kod tekrarını azaltır: Bileşenlerin doğrudan etkileşime girmesini önleyerek kodun sadeleşmesini sağlar.
- Esneklik sağlar: Yeni bileşenler eklendiğinde sistemin geri kalanı etkilenmez.
Dezavantajlar:
- Tek bir merkezi nesneye bağımlılık yaratır: Mediator çok fazla sorumluluk alırsa, tanrı nesne (god object) haline gelebilir.
- Kodun merkezi hale gelmesi: Tüm iletişim aracı nesne üzerinden sağlandığı için, büyük ölçekli sistemlerde yönetilmesi zor olabilir.
Mediator Pattern Kullanım Biçimleri
1. Temel Mediator Kullanımı
import java.util.ArrayList;
import java.util.List;
// Mediator Arayüzü
interface ChatMediator {
void sendMessage(String message, User user);
void addUser(User user);
}
// Concrete Mediator
class ChatRoom implements ChatMediator {
private List<User> users;
public ChatRoom() {
this.users = new ArrayList<>();
}
@Override
public void addUser(User user) {
users.add(user);
}
@Override
public void sendMessage(String message, User sender) {
for (User user : users) {
if (user != sender) {
user.receiveMessage(message);
}
}
}
}
// Colleague (Katılımcı) Sınıfı
abstract class User {
protected ChatMediator mediator;
protected String name;
public User(ChatMediator mediator, String name) {
this.mediator = mediator;
this.name = name;
}
public abstract void sendMessage(String message);
public abstract void receiveMessage(String message);
}
// Concrete Colleague
class ChatUser extends User {
public ChatUser(ChatMediator mediator, String name) {
super(mediator, name);
}
@Override
public void sendMessage(String message) {
System.out.println(name + " gönderdi: " + message);
mediator.sendMessage(message, this);
}
@Override
public void receiveMessage(String message) {
System.out.println(name + " aldı: " + message);
}
}
2. Kullanım
public class Main {
public static void main(String[] args) {
ChatMediator chatRoom = new ChatRoom();
User user1 = new ChatUser(chatRoom, "Ahmet");
User user2 = new ChatUser(chatRoom, "Mehmet");
User user3 = new ChatUser(chatRoom, "Ayşe");
chatRoom.addUser(user1);
chatRoom.addUser(user2);
chatRoom.addUser(user3);
user1.sendMessage("Merhaba arkadaşlar!");
}
}
Çıktı:
Ahmet gönderdi: Merhaba arkadaşlar!
Mehmet aldı: Merhaba arkadaşlar!
Ayşe aldı: Merhaba arkadaşlar!
Gerçek Dünya Senaryosu: Uçuş Kontrol Kulesi
import java.util.ArrayList;
import java.util.List;
// Mediator Arayüzü
interface AirTrafficControl {
void requestLanding(Airplane airplane);
void addAirplane(Airplane airplane);
}
// Concrete Mediator
class AirTrafficController implements AirTrafficControl {
private List<Airplane> airplanes = new ArrayList<>();
@Override
public void addAirplane(Airplane airplane) {
airplanes.add(airplane);
}
@Override
public void requestLanding(Airplane airplane) {
System.out.println(airplane.getName() + " iniş için izin istiyor...");
for (Airplane a : airplanes) {
if (!a.equals(airplane)) {
a.receiveMessage(airplane.getName() + " iniş yapacak.");
}
}
}
}
// Colleague (Katılımcı) Sınıfı
abstract class Airplane {
protected AirTrafficControl controlTower;
protected String name;
public Airplane(AirTrafficControl controlTower, String name) {
this.controlTower = controlTower;
this.name = name;
}
public String getName() {
return name;
}
public abstract void requestLanding();
public abstract void receiveMessage(String message);
}
// Concrete Colleague
class CommercialAirplane extends Airplane {
public CommercialAirplane(AirTrafficControl controlTower, String name) {
super(controlTower, name);
}
@Override
public void requestLanding() {
controlTower.requestLanding(this);
}
@Override
public void receiveMessage(String message) {
System.out.println(name + " bildirimi aldı: " + message);
}
}
Kullanım
public class Main {
public static void main(String[] args) {
AirTrafficControl controlTower = new AirTrafficController();
Airplane plane1 = new CommercialAirplane(controlTower, "THY123");
Airplane plane2 = new CommercialAirplane(controlTower, "Lufthansa456");
controlTower.addAirplane(plane1);
controlTower.addAirplane(plane2);
plane1.requestLanding();
}
}
Çıktı:
THY123 iniş için izin istiyor...
Lufthansa456 bildirimi aldı: THY123 iniş yapacak.
Sonuç
Mediator Design Pattern, nesneler arasındaki bağımlılığı azaltarak, sistemin daha modüler hale gelmesini sağlar. Gerçek dünyada şu senaryolarda yaygın olarak kullanılır:
- Hava trafik kontrol sistemleri
- Mesajlaşma ve sohbet sistemleri
- GUI bileşenleri arasında etkileşim yönetimi
- Merkezi yönetim sistemleri
Mediator Pattern, sistemin ölçeklenebilir ve bakımı kolay bir hale gelmesini sağlar. 🚀