Behavioral design patternlerden biri olan mediator patternin temel amacı nesneler arasındaki karmaşık iletişim sürecinin ortak bir nesne üzerinden yürümesini sağlayarak bağımlılığı azaltmak, sadeleştirmek ve daha yönetilebilir hale getirmektir. Tasarım kalıbı için verilen çok güzel bir gerçek hayat örneği var genelde her yerde bu örneği görürüz şöyleki, bir hava limanı düşünün bir çok uçak iniş veya kalkış yapıyor, iletişim ise her zaman kule üzerinden gerçekleşiyor, talimatlar kuleden veriliyor veya talimatları sadece kule alıyor, bir uçak başka bir uçakla asla iletişime geçmiyor, işte bu organizasyondaki kule tüm iletişim sürecinin üzerinden yürüdüğü mediator oluyor.
Mediator patternin, özellikle büyük ve karmaşık sistemlerde kullanışlılığı ve faydasını görmek daha kolaydır. Sistemin ölçeklenebilirliğini artırır ve bakımını kolaylaştırır. Aynı zamanda nesneler arasındaki bağımlılıkları azalttığından, kodun yeniden kullanılabilirliğinide (reusability) artırır. Single Responsibility ve Open-open prensiplerinden yola çıkacak olursak her sınıf veya method tek bir görevi yerine getirmeli, aynı zamanda değişime kapalı ama gelişime açık olmalı, bu noktada single responsibility için yapılarımızı ayırdığımızda birim sayısı artacaktır, buna bağlı olarakta bu birimlerin aralarındaki iletişim oklarının sayısı, karmaşıklığı ve bağımlılığıda artaracağından, günün sonunda bir sınıfın bir methodu veya kendisi değiştirilmek istendiğinde bir çok kısmı incelemek gerekecekti ve geliştirme maliyeti yükselerek open-open’a ters düşecekti, mediator bu noktada yeniden kullanılabilirlik, modülerlik ve esnekliği artırmış oluyor.
Mediator tasarım deseninin diagramını incelediğimizde bir Mediator arayüzü görüyoruz. Bu arayüz veya sınıf, nesnelerle iletişim için yöntemleri tanımlar. Her nesne, diğer nesnelerle iletişim kurmak için Mediator’a kaydedilir ve Mediator, kayıtlı nesnelerin listesini tutar. Bir nesne, başka bir nesneyle iletişim kurmak istediğinde, bir mesajı Mediator’a gönderir ve Mediator, mesajı uygun nesneye iletir. Colleague nesnesi ise bir birleriyle iletişim kuracak somut sınıfların uygulayacağı arayüzü belirtiyor.
Örnek bir senaryo üzerinden kodlayacak olursa: bir uçuş rezervasyon sistemi yazdığımızı düşünelim. Bu sistemin Mediator sınıfı, uçuşlar arasındaki iletişimi yönetirken, Colleague sınıfları ise yolcu ve uçuş gibi nesneleri temsil ediyor olsun. Kısacası uçuşlar ile yolcuların rezervasyon işlemlerini mediator pattern ile gerçekleştirelim.
from abc import ABC, abstractmethod
class FlightMediator(ABC):
@abstractmethod
def book_seat(self, flight, passenger):
pass
class ConcreteFlightMediator(FlightMediator):
def __init__(self):
self.flights = []
self.passengers = {}
def register_flight(self, flight):
self.flights.append(flight)
def register_passenger(self, passenger):
self.passengers[passenger.name] = passenger
def book_seat(self, flight, passenger):
if flight in self.flights and passenger in self.passengers.values():
print(f"# Booking seat for {passenger.name} on {flight.flight_number}")
flight.book_seat(passenger)
class Flight:
def __init__(self, flight_number, capacity):
self.flight_number = flight_number
self.capacity = capacity
self.passengers = set()
def book_seat(self, passenger):
if len(self.passengers) < self.capacity:
self.passengers.add(passenger)
print(f"+ Seat booked for {passenger.name} on flight {self.flight_number}")
else:
print(f"- No available seats on flight {self.flight_number}")
class Passenger:
def __init__(self, name):
self.name = name
if __name__ == '__main__':
mediator = ConcreteFlightMediator()
flight1 = Flight("ABC123", 3)
flight2 = Flight("DEF456", 2)
mediator.register_flight(flight1)
mediator.register_flight(flight2)
alice = Passenger("Alice")
bob = Passenger("Bob")
charlie = Passenger("Charlie")
mediator.register_passenger(alice)
mediator.register_passenger(bob)
mediator.register_passenger(charlie)
mediator.book_seat(flight1, alice)
mediator.book_seat(flight1, bob)
mediator.book_seat(flight1, charlie)
mediator.book_seat(flight2, alice)
mediator.book_seat(flight2, bob)
mediator.book_seat(flight2, charlie)
-----------------------------------------------------------------------
Output:
# Booking seat for Alice on ABC123
+ Seat booked for Alice on flight ABC123
# Booking seat for Bob on ABC123
+ Seat booked for Bob on flight ABC123
# Booking seat for Charlie on ABC123
+ Seat booked for Charlie on flight ABC123
# Booking seat for Alice on DEF456
+ Seat booked for Alice on flight DEF456
# Booking seat for Bob on DEF456
+ Seat booked for Bob on flight DEF456
# Booking seat for Charlie on DEF456
- No available seats on flight DEF456
FlightMediator
arayüzü, aracı nesneyi (Mediator) temsil eder. ConcreteFlightMediator
sınıfı ise, Flight
ve Passenger
nesneleri (Colleague nesneleri) book_seat
metodunu çağırdığında, birbirine bağlayarak rezervasyon işlemlerinin gerçekleştirilmesini sağlar. Günün sonunda sisteme yeni bir Flight
veya Passenger
nesnesi eklendiğinde, bunları ConcreteFlightMediator
sınıfına register etmek yeterli olacaktır.
Mediator tasarım desenini uygularken dikkat edilmesi gereken hususlardan en önemlisi bir çok nesnenin iletişimi sağlanırken karmaşık ve büyük mediator nesneleri oluşma ihtimali vardır bu durumda bakım ve geliştirme maliyetleride doğrudan artıyor olacaktır, aynı zamanda nesneler arasındaki iletişime ara bir katman giriyor olacağından belirli bir aşamada performansı düşürebilir, bu takası göze alıp hesaplayarak (performans x karmaşıklık) mediator patternin uygulanması faydalı olacaktır.
Be First to Comment