Factory Deseni: Nesne Üretim Kararını Tek Yerde Toplamak
Beceri rehberi

Factory Deseni: Nesne Üretim Kararını Tek Yerde Toplamak

Hazırlayan: Mindset Institute EditörlüğüGüncellendi: 6 dk okuma

Basit fabrika, fabrika metodu ve soyut fabrika arasındaki farkı, kod örnekleri ve sık yapılan hatalarla öğrenin; hangisini ne zaman seçeceğinizi görün.

Factory deseni hangi sorunu çözer?

Bir nesneyi oluşturmak için doğrudan new yazmak masum görünür. Sorun, hangi sınıfın oluşturulacağının koşullara bağlı olduğu anda başlar: kullanıcının seçtiği ödeme yöntemi, yapılandırmadaki bildirim kanalı, çalıştığınız ortam. Bu karar kodun her yerinde bir if ya da switch zinciriyle tekrarlanırsa, yeni bir seçenek eklemek onlarca dosyaya dokunmak demektir ve bir yeri unutmak çalışma zamanında hataya dönüşür.

Factory (fabrika) deseni, hangi somut sınıfın üretileceği kararını tek bir yerde toplar. Çağıran kod yalnızca ne istediğini söyler ("e-posta kanalından bir bildirimci ver"); nasıl ve hangi sınıftan üretildiği fabrikanın içinde kalır. Böylece çağıran taraf somut sınıfları tanımaz, yalnızca ortak arayüzü bilir. Bu, SOLID prensiplerinden bağımlılığın soyutlamaya yönelmesi fikrinin en pratik uygulamalarından biridir.

Desenin değeri, nesne oluşturmanın gerçekten karar gerektirdiği yerlerde ortaya çıkar. Her sınıf için bir fabrika yazmak değil, değişme ihtimali olan oluşturma noktalarını işaretlemek gerekir. Oluşturma mantığı basit ve sabitse doğrudan new kullanmak daha okunaklıdır.

Basit fabrika, fabrika metodu ve soyut fabrika: fark nedir?

"Factory" adı altında birbirinden farklı birkaç yapı karıştırılır. Hangisine ihtiyacınız olduğunu bilmek, deseni gereğinden ağır uygulamaktan korur.

  • Basit fabrika: Parametreye bakıp uygun nesneyi döndüren tek bir fonksiyon ya da sınıftır. Resmî bir tasarım deseni olarak sayılmaz ama en sık kullanılan biçimidir. Yeni seçenek eklendiğinde fabrikanın içi değişir.
  • Fabrika metodu (Factory Method): Üst sınıf bir oluşturma metodunu soyut olarak tanımlar, alt sınıflar hangi nesnenin üretileceğine karar verir. Üst sınıftaki iş akışı sabit kalır, yalnızca üretilen parça değişir.
  • Soyut fabrika (Abstract Factory): Birbiriyle uyumlu bir nesne ailesini üretir. Örneğin koyu temada düğme, girdi alanı ve pencere birlikte koyu temaya ait olmalıdır; soyut fabrika bu ailenin karışmamasını yapısal olarak sağlar.

Karar ölçütü basittir. Tek bir nesne türü seçiyorsanız basit fabrika yeter. Bir iş akışının ortasında değişen bir adım varsa fabrika metodu uygundur. Birlikte değişmesi gereken birden fazla nesne türü varsa soyut fabrikaya geçersiniz.

Adım adım uygulama: bildirim gönderici örneği

Örneğin bir sipariş tamamlandığında müşteriye e-posta, kısa mesaj ya da uygulama bildirimi göndermeniz gerekiyor. Önce ortak arayüzü tanımlarsınız, sonra somut sınıfları, en sonda fabrikayı.

Birinci adım, çağıranın bilmesi gereken sözleşmeyi yazmaktır:

interface Notifier { send(recipient: string, message: string): void; }

İkinci adım, her kanal için bir gerçekleme yazmaktır:

class EmailNotifier implements Notifier { send(recipient: string, message: string) { /* e-posta servisine ilet */ } } class SmsNotifier implements Notifier { send(recipient: string, message: string) { /* sms servisine ilet */ } }

Üçüncü adım, kararı tek yerde toplayan fabrikayı yazmaktır:

class NotifierFactory { static create(channel: string): Notifier { switch (channel) { case "email": return new EmailNotifier(); case "sms": return new SmsNotifier(); default: throw new Error("Bilinmeyen kanal: " + channel); } } }

Dördüncü adımda çağıran kod somut sınıfı hiç görmez:

const notifier = NotifierFactory.create(customer.preferredChannel); notifier.send(customer.contact, "Siparişiniz tamamlandı.");

Artık yeni bir kanal eklemek yalnızca yeni sınıf ve fabrikada bir satır demektir. Bilinmeyen kanal için sessizce varsayılan döndürmek yerine hata fırlatmak, yapılandırma hatalarını erken yakalamanızı sağlar.

Fabrika metodu ile iş akışını sabit tutmak

Bildirimin hangi kanaldan gideceği değil de, iş akışının kendisi sabitken yalnızca bir parçanın değiştiği durumlarda fabrika metodu daha doğal bir uyumdur. Üst sınıf akışı yönetir, alt sınıf yalnızca ürettiği nesneyi belirler:

abstract class OrderCompleter { complete(order: Order) { order.updateStatus("completed"); const notifier = this.createNotifier(); notifier.send(order.customerContact, "Siparişiniz tamamlandı."); } protected abstract createNotifier(): Notifier; }

class EmailOrderCompleter extends OrderCompleter { protected createNotifier() { return new EmailNotifier(); } }

Bu yapıda "sipariş durumunu güncelle, sonra bildir" sırası tek bir yerde durur; alt sınıflar bu sırayı bozamaz. Bedeli, her varyasyon için bir alt sınıf yazmaktır. Varyasyon sayısı arttıkça kalıtım hiyerarşisi büyür; o noktada fabrikayı bir bağımlılık olarak dışarıdan vermek (bileşim) genellikle daha sürdürülebilirdir.

Soyut fabrika: birlikte çalışan nesne ailesi

Bir arayüz kitinde düğme ve onay kutusunun aynı görsel temadan gelmesi gerekir. Karışık üretim, ekranda tutarsız görünüm demektir. Soyut fabrika bu tutarlılığı yapıya gömer:

interface TemaFabrikasi { dugmeOlustur(): Dugme; onayKutusuOlustur(): OnayKutusu; } class KoyuTemaFabrikasi implements TemaFabrikasi { /* koyu aile */ } class AcikTemaFabrikasi implements TemaFabrikasi { /* açık aile */ }

Uygulama açılışında tek bir fabrika seçilir ve arayüzü kuran bütün kod yalnızca TemaFabrikasi tipini bilir. Aynı mantık farklı veritabanı sürücüleri (bağlantı, komut ve okuyucu nesnelerinin birlikte değişmesi), farklı ödeme sağlayıcıları ya da test ortamında gerçek yerine sahte servis ailesi kurmak için de geçerlidir.

Soyut fabrikanın zayıf yanı, aileye yeni bir ürün türü eklemenin (örneğin bir üçüncü bileşen) tüm fabrikaları değiştirmeyi gerektirmesidir. Bu yüzden ürün türleri sık değişiyorsa desen yük olur; aile sayısı değişiyor ama ürün türleri sabitse çok iyi çalışır.

Sık yapılan hatalar ve nasıl önlenir

  • Her şeyi fabrikaya sarmak: Basit, sabit nesneler için fabrika yazmak kodu uzatır ve okuyucuyu yanıltır. Fabrika yalnızca karar veya karmaşık kurulum varsa anlam taşır.
  • Fabrikanın tanrı sınıfa dönüşmesi: Yeni ürünler eklendikçe dev bir switch bloğu oluşursa, kayıt tabanlı bir yaklaşım düşünün: kanal adından üretici fonksiyona giden bir eşleme tablosu tutun ve yeni türler kendilerini bu tabloya kaydetsin.
  • Statik fabrikayı her yere gömmek: Statik metot test sırasında değiştirilemez. Fabrikayı bir nesne olarak çağıran sınıfa dışarıdan verirseniz testte sahte fabrika kullanabilirsiniz.
  • Fabrikada iş mantığı yazmak: Fabrikanın görevi üretmektir; ürettiği nesnenin kararlarını vermek değildir. Doğrulama ve iş kuralları ürünün kendi sınıfında kalmalıdır.
  • Dönüş tipini somut sınıf yapmak: Fabrika Bildirimci yerine EpostaBildirimci döndürürse desenin sağladığı gevşek bağlılık kaybolur.

Bir kontrol sorusu işe yarar: fabrikayı kaldırırsam çağıran kod hangi somut sınıfları tanımak zorunda kalır? Cevap "hiçbiri" ise desen işini yapıyordur.

Test edilebilirlik ve bağımlılık enjeksiyonu ile ilişkisi

Fabrikalar ile bağımlılık enjeksiyonu (dependency injection) birbirinin alternatifi değil, tamamlayıcısıdır. Enjeksiyon konteyneri çoğu zaman uygulamanın kök noktasında bir tür soyut fabrika gibi davranır: arayüz istenir, yapılandırmaya göre somut sınıf üretilir. Çalışma zamanında parametreye bağlı karar gerektiğinde (kullanıcının seçtiği kanal gibi) ise elle yazılmış bir fabrika, konteynerin bilemeyeceği bu kararı üstlenir.

Test açısından kazanç belirgindir. Çağıran sınıf Bildirimci arayüzünü ve fabrikayı dışarıdan aldığında, testte hiçbir gerçek e-posta göndermeden "doğru kanal seçildi mi" ve "mesaj iletildi mi" sorularını sahte nesnelerle doğrulayabilirsiniz. Oluşturma mantığının kendisi de ayrı bir birim testiyle sınanır: bilinen her kanal için doğru tipte nesne döner, bilinmeyen kanal hata fırlatır.

Desenleri ezberlemek yerine hangi değişimin sizi acıttığını sormak daha verimlidir. Oluşturma kararı dağılmış ve sık değişiyorsa fabrika, değişmiyorsa sade new yeterlidir.

Bu beceriyi Mindset programında nerede çalışırsınız?

Yazılım Mimarisi ve Tasarım Desenleri programı, tasarım desenlerini yaratıcı, yapısal ve davranışsal olarak ayrı modüllerde işler; fabrika ve soyut fabrika gibi nesne üretim desenleri yaratıcı desenler modülünün konusudur. Program, mevcut kod tabanında tasarım kararı veren geliştiriciler ve teknik liderler için, desenleri bağlama bakmadan uygulamak yerine SOLID ve tasarım prensipleriyle birlikte düşünme alışkanlığı kazandırmaya yöneliktir.

Kurumsal ekipler için pratik uygulama alanı, ekip içinde ortak bir tasarım dili kurmaktır: kod incelemesinde "burada fabrika gerekir mi" sorusunu aynı kavramlarla tartışabilmek ve oluşturma mantığının dağıldığı noktaları birlikte bulmak.

İlgili Mindset programı

Yazılım Mimarisi ve Tasarım Desenleri

Sık sorulanlar

Sık sorulan sorular

Factory deseni ile new anahtar sözcüğü arasında ne fark var?

new, somut bir sınıfı doğrudan adıyla bağlar; çağıran kod o sınıfa bağımlı hale gelir. Factory deseninde çağıran taraf yalnızca arayüzü bilir, hangi sınıfın üretileceği fabrikanın içindeki karara bırakılır. Karar sabitse new yeterlidir; kanal, ortam ya da kullanıcı tercihi gibi bir koşula bağlıysa fabrika bu kararı tek yerde toplar ve değişiklik maliyetini düşürür.

Basit fabrika ile fabrika metodu aynı şey mi?

Hayır. Basit fabrika, parametreye göre nesne döndüren tek bir fonksiyondur ve kalıtım gerektirmez. Fabrika metodu ise üst sınıftaki soyut bir metodu alt sınıfların doldurmasına dayanır; iş akışı sabit kalır, üretilen parça alt sınıfa göre değişir. Pratikte çoğu proje basit fabrikayla başlar, iş akışını sabitlemek gerektiğinde fabrika metoduna geçer.

Soyut fabrika ne zaman gereğinden fazla olur?

Tek bir nesne türünü seçiyorsanız soyut fabrika gereğinden fazladır. Desen, birlikte değişmesi gereken birden çok ilişkili nesne olduğunda değer kazanır, örneğin aynı temaya ait tüm arayüz bileşenleri. Ürün türleri sık eklenen bir yapıda ise her yeni tür tüm fabrikaları değiştirmeyi gerektirir ve desen yük haline gelir.

Factory deseni bağımlılık enjeksiyonunun yerini alır mı?

Yerini almaz, birlikte kullanılır. Enjeksiyon konteyneri uygulama kurulurken genel bağımlılıkları sağlar; fabrika ise çalışma zamanında verilen bir değere göre hangi nesnenin üretileceğine karar verir. Fabrikayı bir nesne olarak enjekte etmek, hem esnekliği korur hem de testlerde sahte fabrika kullanmanızı sağlar.

Fabrikayı test etmek için ne yazmalıyım?

Bilinen her giriş değeri için fabrikanın beklenen tipte nesne döndürdüğünü ve bilinmeyen değerde anlamlı bir hata fırlattığını sınayan küçük birim testleri yeterlidir. Fabrikayı kullanan sınıfların testlerinde ise gerçek üretim yerine sahte fabrika verirsiniz; böylece dış servislere dokunmadan davranışı doğrularsınız.

Factory Deseni Nasıl Uygulanır? Adım Adım Örnek