Structural — Yapısal Desenler
Facade
Cephe (Ön Yüz) Deseni
Amaç: Karmaşık bir alt sistem için basit, tek bir giriş noktası sunmak.
Basit Anlatım
Teknik terim yok — günlük hayattan bir benzetme
Bir otelde kaldığınızı düşünün. Akşam yemeği için restoran rezervasyonu, sabah için taksi, odaya ekstra yastık ve bir de tiyatro bileti istiyorsunuz.
Restoranı, taksi firmasını, kat hizmetlerini ve tiyatro gişesini tek tek aramak yerine resepsiyonu ararsınız. "Şunları istiyorum" dersiniz, gerisini resepsiyon halleder. Arka planda kimi aradığını, hangi sırayla ne yaptığını bilmenize gerek yok.
Arabanın kontağı
Arabanızı çalıştırmak için anahtarı çevirirsiniz. Arka planda akü devreye girer, yakıt pompası çalışır, marş motoru döner, ateşleme sistemi kıvılcım üretir. Siz tüm bunları tek bir hareketle yaparsınız. Kontak, motorun karmaşık sistemlerinin cephesidir.
Teknik Anlamı
Bir yazılımcının bakış açısıyla
Facade, birden fazla sınıftan oluşan bir alt sistemin önüne konan sadeleştirilmiş bir arayüzdür. Alt sistemi gizlemez veya kilitlemez; gerekirse doğrudan erişim hâlâ mümkündür. Amaç, en yaygın kullanım senaryolarını kolaylaştırmaktır.
Katılımcılar
- Facade: İstemciden gelen isteği uygun alt sistem nesnelerine yönlendirir ve doğru sırada çağırır (
OrderFacade). - Subsystem classes: Asıl işi yapan sınıflar. Facade'dan haberdar değillerdir (
InventoryService,PaymentService,ShippingService...). - Client: Alt sistem yerine Facade ile konuşur.
Ne zaman kullanılır?
- Karmaşık bir kütüphaneyi / alt sistemi basit bir API ile sunmak istediğinizde.
- Katmanlı mimaride katmanlar arası giriş noktası tanımlamak için (ör. Application Service katmanı aslında bir facade'dır).
- İstemcinin alt sistemin birçok sınıfına bağımlı olmasını engellemek için.
Avantajlar
- İstemci ile alt sistem arasındaki bağımlılık azalır.
- Kod okunabilirliği ve kullanım kolaylığı artar.
Dezavantajlar
- Dikkat edilmezse her şeyi bilen ve her şeyi yapan bir God Object'e dönüşebilir.
C# ile Uygulama
Adım adım, çalışan kod örneği
Senaryo: Bir e-ticaret sitesinde sipariş vermek; stok kontrolü, ödeme, kargo ve bildirim gibi birden fazla servisi doğru sırayla çağırmayı gerektiriyor.
Adım 1 Alt sistem sınıfları
Her biri kendi işini bilir ama birbirinden habersizdir.
public class InventoryService
{
public bool IsInStock(string product)
{
Console.WriteLine($" [Stok] {product} kontrol edildi: mevcut");
return true;
}
public void Reserve(string product) =>
Console.WriteLine($" [Stok] {product} rezerve edildi");
}
public class PaymentService
{
public bool Charge(string customer, decimal amount)
{
Console.WriteLine($" [Ödeme] {customer} kartından {amount} TL çekildi");
return true;
}
}
public class ShippingService
{
private int _lastTrackingNo = 5000;
public string CreateShipment(string product, string address)
{
Console.WriteLine($" [Kargo] {product} -> {address}");
return $"TRK-{++_lastTrackingNo}";
}
}
public class NotificationService
{
public void SendEmail(string customer, string message) =>
Console.WriteLine($" [E-posta] {customer}: {message}");
}Adım 2 Facade: tek ve basit giriş noktası
Doğru sıralamayı ve hata durumlarını Facade yönetir. İstemci sadece PlaceOrder çağırır.
public class OrderFacade
{
private readonly InventoryService _inventory = new();
private readonly PaymentService _payment = new();
private readonly ShippingService _shipping = new();
private readonly NotificationService _notification = new();
public bool PlaceOrder(string customer, string product, decimal price, string address)
{
Console.WriteLine($"Sipariş başlıyor: {product}");
if (!_inventory.IsInStock(product)) return false;
_inventory.Reserve(product);
if (!_payment.Charge(customer, price)) return false;
string tracking = _shipping.CreateShipment(product, address);
_notification.SendEmail(customer, "Siparişiniz kargoya verildi.");
Console.WriteLine($"Sipariş tamamlandı. Takip no: {tracking}");
return true;
}
}Adım 3 Kullanım
Facade olmasaydı istemci dört servisi tanımak ve doğru sırayla çağırmak zorundaydı. Şimdi tek satır yeterli:
var shop = new OrderFacade();
shop.PlaceOrder("ali@mail.com", "Kulaklık", 1299.90m, "Kadıköy, İstanbul");Konsol çıktısı
Sipariş başlıyor: Kulaklık [Stok] Kulaklık kontrol edildi: mevcut [Stok] Kulaklık rezerve edildi [Ödeme] ali@mail.com kartından 1299,90 TL çekildi [Kargo] Kulaklık -> Kadıköy, İstanbul [E-posta] ali@mail.com: Siparişiniz kargoya verildi. Sipariş tamamlandı. Takip no: TRK-5001
Kodda dikkat edilmesi gerekenler
- İstemci,
InventoryServiceya daShippingServicegibi sınıfların varlığından bile habersiz. - Alt sistemde değişiklik olursa (ör. ödeme sağlayıcısı değişirse) yalnızca Facade güncellenir; istemci kodu etkilenmez.