Behavioral — Davranışsal Desenler
Mediator
Arabulucu Deseni
Amaç: Nesnelerin birbirleriyle doğrudan konuşmasını engelleyip tüm iletişimi merkezi bir arabulucu üzerinden yürütmek; böylece aralarındaki bağımlılığı azaltmak.
Basit Anlatım
Teknik terim yok — günlük hayattan bir benzetme
Bir havalimanını düşünün. Onlarca uçak iniş ve kalkış yapmak istiyor. Pilotlar birbirleriyle konuşup "Sen önce in, ben sonra" diye anlaşmaya çalışsaydı tam bir kaos olurdu.
Bunun yerine her pilot yalnızca kontrol kulesi ile konuşur. Kule tüm resmi görür ve kimin ne zaman ineceğine karar verir. Pilotlar birbirini tanımak zorunda değildir.
Neden önemli?
10 kişilik bir grupta herkes herkesle ayrı ayrı konuşursa 45 farklı iletişim hattı oluşur. Bir koordinatör olursa sadece 10 hat yeterlidir: herkes koordinatörle konuşur.
Teknik Anlamı
Bir yazılımcının bakış açısıyla
Mediator, bir grup nesnenin (colleague) birbirleriyle nasıl etkileşime gireceğini kapsülleyen bir nesne tanımlar. Colleague'ler birbirlerine referans tutmaz; yalnızca mediator'ı bilirler. Bu, çoktan-çoğa (many-to-many) ilişkileri bire-çoğa (one-to-many) ilişkilere dönüştürür.
Katılımcılar
- Mediator: Colleague'lerle iletişim arayüzü (
IChatRoom). - ConcreteMediator: Colleague'leri koordine eden mantık (
ChatRoom). - Colleague: Diğer nesnelerle mediator üzerinden konuşan nesneler (
User).
Gerçek dünya kullanımları
- Sohbet odaları, form ekranlarındaki birbirine bağlı kontroller (bir checkbox seçilince başka bir alanın aktifleşmesi)
- MediatR kütüphanesi: Controller'lar handler'ları doğrudan çağırmaz;
_mediator.Send(new CreateOrderCommand(...))ile isteği mediator'a gönderir.
Observer'dan farkı
Observer'da yayıncı, abonelerine tek yönlü bildirim yapar. Mediator'da ise nesneler arasındaki karmaşık, çift yönlü etkileşim mantığı merkezi bir yerde toplanır.
Avantajlar
- Colleague'ler arasındaki sıkı bağlılık ortadan kalkar.
- Etkileşim mantığı tek bir yerde toplanır, anlaşılması ve değiştirilmesi kolaylaşır.
- Colleague'ler bağımsız olarak yeniden kullanılabilir.
Dezavantajlar
- Mediator zamanla her şeyi bilen bir God Object'e dönüşebilir.
C# ile Uygulama
Adım adım, çalışan kod örneği
Senaryo: Bir sohbet odası. Kullanıcılar birbirine doğrudan mesaj göndermez; oda (mediator) mesajları dağıtır, özel mesajları yönlendirir ve yasaklı kelimeleri filtreler.
Adım 1 Mediator arayüzü
public interface IChatRoom
{
void Join(User user);
void Broadcast(User from, string message);
void SendPrivate(User from, string toName, string message);
}Adım 2 Colleague: kullanıcı
User diğer kullanıcıları hiç tanımaz; sadece odaya referans tutar.
public class User
{
private IChatRoom? _room;
public string Name { get; }
public User(string name) => Name = name;
public void Enter(IChatRoom room) { _room = room; room.Join(this); }
public void Say(string message) => _room?.Broadcast(this, message);
public void Whisper(string to, string message) => _room?.SendPrivate(this, to, message);
public void Receive(string from, string message) =>
Console.WriteLine($" {Name,-6} <- {from}: {message}");
}Adım 3 ConcreteMediator: tüm iletişim kuralları burada
public class ChatRoom : IChatRoom
{
private readonly Dictionary<string, User> _users = new();
private static readonly string[] BannedWords = { "spam", "reklam" };
public void Join(User user)
{
_users[user.Name] = user;
Console.WriteLine($" * {user.Name} odaya katıldı");
}
public void Broadcast(User from, string message)
{
if (BannedWords.Any(w => message.Contains(w, StringComparison.OrdinalIgnoreCase)))
{
Console.WriteLine($" ! {from.Name} kullanıcısının mesajı engellendi");
return;
}
Console.WriteLine($" {from.Name} herkese yazdı:");
foreach (var u in _users.Values.Where(u => u != from))
u.Receive(from.Name, message);
}
public void SendPrivate(User from, string toName, string message)
{
if (_users.TryGetValue(toName, out var target))
{
Console.WriteLine($" {from.Name} -> {toName} (özel):");
target.Receive(from.Name, "[özel] " + message);
}
}
}Adım 4 Kullanım
Tüm parçaları bir araya getiren istemci (client) kodu:
var room = new ChatRoom();
var ali = new User("Ali");
var veli = new User("Veli");
var ayse = new User("Ayşe");
ali.Enter(room);
veli.Enter(room);
ayse.Enter(room);
ali.Say("Herkese merhaba!");
veli.Whisper("Ayşe", "Toplantı 15:00'te");
ayse.Say("Ucuz REKLAM fırsatı!!!");Konsol çıktısı
* Ali odaya katıldı
* Veli odaya katıldı
* Ayşe odaya katıldı
Ali herkese yazdı:
Veli <- Ali: Herkese merhaba!
Ayşe <- Ali: Herkese merhaba!
Veli -> Ayşe (özel):
Ayşe <- Veli: [özel] Toplantı 15:00'te
! Ayşe kullanıcısının mesajı engellendiKodda dikkat edilmesi gerekenler
Usersınıfında başka birUser'a referans yok. Kullanıcılar birbirinden tamamen bağımsız.- Filtreleme, özel mesaj, yayın gibi tüm kurallar
ChatRoomiçinde. Yeni bir kural (ör. moderatör onayı) eklemek için yalnızca mediator değişir.