Factory Kalıbı
Coddy'nin PHP Journey'sinin Nesne Yönelimli Programlama bölümünün bir parçası — ders 72 / 91.
Factory Tasarım Deseni, nesne oluşturma işlemini ayrı bir sınıfa veya metoda devreden, nesne oluşturmaya yönelik (creational) bir tasarım desenidir. Kodunuzun her yerinde doğrudan new kullanmak yerine, nesneleri sizin için oluşturması için bir fabrikadan talepte bulunursunuz.
Bu desen, özellikle ortak bir arayüzü paylaşan birden fazla ilişkili sınıfınız olduğunda ve hangisinin örnekleneceğine belirli bir koşula göre karar vermek istediğinizde oldukça kullanışlıdır. Farklı kanallar üzerinden mesaj gönderebilen bir bildirim sistemini düşünün:
<?php
interface Notification {
public function send(string $message): string;
}
class EmailNotification implements Notification {
public function send(string $message): string {
return "Email: $message";
}
}
class SmsNotification implements Notification {
public function send(string $message): string {
return "SMS: $message";
}
}
Bir fabrika (factory) olmadan, if ifadelerini ve new çağrılarını her yere dağıtırsınız. Fabrika bu mantığı merkezileştirir:
<?php
class NotificationFactory {
public static function create(string $type): Notification {
return match($type) {
'email' => new EmailNotification(),
'sms' => new SmsNotification(),
default => throw new InvalidArgumentException("Unknown type: $type")
};
}
}
$notification = NotificationFactory::create('email');
echo $notification->send('Hello!');
Çıktı:
Email: Hello!Temel avantaj, kodunuzun somut sınıflara değil, Notification arayüzüne bağlı olmasıdır. Daha sonra bir PushNotification sınıfı eklerseniz, sadece fabrikayı güncellersiniz. Fabrikayı kullanan tüm kodlar, herhangi bir değişiklik yapılmadan yeni türe otomatik olarak erişim sağlar.
Görev
KolayFabrika Deseni'ni (Factory Pattern) kullanarak bir belge oluşturucu sistemi inşa edelim. Farklı belge türleri (PDF, HTML, Düz Metin) ortak bir arayüzü paylaşır ancak farklı çıktılar üretir — bu, nesne oluşturma işlemini bir fabrikada merkezileştirmek için mükemmel bir senaryodur.
Kodunuzu dört dosya halinde düzenleyeceksiniz:
Document.php— Tüm belge türlerinin uyması gereken sözleşmeyi tanımlayan birDocumentarayüzü oluşturun. İçeriği alan ve biçimlendirilmiş belge çıktısını döndüren tek birrender(string $content): stringmetoduna sahip olmalıdır.Documents.php— Document arayüzünü dahil edin ve onu uygulayan (implement) üç sınıf oluşturun:PdfDocument—render()metodu"PDF: [content]"döndürürHtmlDocument—render()metodu"<html>[content]</html>"döndürürTextDocument—render()metodu"TXT: [content]"döndürür
DocumentFactory.php— Documents dosyasını dahil edin ve statik bircreate(string $type): Documentmetoduna sahip birDocumentFactorysınıfı oluşturun. Bu metot, türe bağlı olarak uygun belge nesnesini döndürmek içinmatchkullanmalıdır:"pdf"birPdfDocumentörneği döndürür"html"birHtmlDocumentörneği döndürür"text"birTextDocumentörneği döndürür- Diğer tüm türler,
"Unknown document type: [type]"mesajıyla birInvalidArgumentExceptionfırlatmalıdır
main.php— DocumentFactory dosyasını dahil edin. İki girdi alacaksınız: bir belge türü ve işlenecek içerik.Uygun belge türünü oluşturmak için fabrikayı kullanın, ardından içerikle birlikte
render()metodunu çağırın ve sonucu yazdırın.Yeni bir satırda, bu desenin neden değerli olduğunu vurgulamak için
"Factory benefit: Adding new types only requires updating the factory"yazdırın.
Fabrika Deseni kodunuzu esnek tutar — daha sonra bir MarkdownDocument eklemeniz gerektiğinde, mevcut tüm kodlar değişmeden çalışmaya devam ederken yalnızca fabrikayı güncellemeniz yeterli olacaktır.
Kopya kağıdı
Factory Deseni (Factory Pattern), nesne oluşturma işlemini kodunuzun her yerinde doğrudan new kullanmak yerine ayrı bir sınıfa veya yönteme devreder.
Bu desen, ortak bir arayüzü (interface) paylaşan birden fazla ilgili sınıfınız olduğunda ve bir koşula bağlı olarak hangisinin örnekleneceğine karar vermeniz gerektiğinde kullanışlıdır.
Bir bildirim sistemi ile örnek:
<?php
interface Notification {
public function send(string $message): string;
}
class EmailNotification implements Notification {
public function send(string $message): string {
return "Email: $message";
}
}
class SmsNotification implements Notification {
public function send(string $message): string {
return "SMS: $message";
}
}
Factory, nesne oluşturma mantığını merkezileştirir:
<?php
class NotificationFactory {
public static function create(string $type): Notification {
return match($type) {
'email' => new EmailNotification(),
'sms' => new SmsNotification(),
default => throw new InvalidArgumentException("Unknown type: $type")
};
}
}
$notification = NotificationFactory::create('email');
echo $notification->send('Hello!'); // Output: Email: Hello!
Temel avantajlar:
- Kod somut sınıflara değil, arayüze bağlıdır
- Yeni türler eklemek yalnızca factory'nin güncellenmesini gerektirir
- Mevcut kod, herhangi bir değişiklik yapılmadan yeni türlere otomatik olarak erişim kazanır
Kendin dene
<?php
require_once 'DocumentFactory.php';
// Girişi oku
$type = trim(fgets(STDIN));
$content = trim(fgets(STDIN));
// YAPILACAK: Uygun belge türünü oluşturmak için DocumentFactory kullanın
// YAPILACAK: İçerikle birlikte render() metodunu çağırın ve sonucu yazdırın
// YAPILACAK: Yeni bir satıra "Factory benefit: Adding new types only requires updating the factory" yazdırın
?>Bu ders kısa bir quiz içerir. Soruları yanıtlamak ve ilerlemeni kaydetmek için derse başla.
Nesne Yönelimli Programlama bölümündeki tüm dersler
1OOP Temelleri
Harici DosyalarOOP'ye GirişSınıflar ve Nesneler$this Anahtar KelimesiMetotlarÖzelliklerYapıcı Metot (__construct)Yıkıcı Metot (__destruct)Özet - Basit Hesap Makinesi4Kalıtım
Temel Kalıtımparent:: Anahtar KelimesiMetot Geçersiz Kılmafinal Anahtar KelimesiSoyut SınıflarÖzet - Çalışan Hiyerarşisi7Kapsülleme
Public, Protected, PrivateErişim Belirleyicilere Derinlemesine BakışGetter ve Setter MetotlarıBilgi GizlemeConstructor Promotion (8.0)Özet - Öğrenci Kayıt Sistemi10İleri Düzey OOP Kavramları
Kompozisyon vs KalıtımDependency InjectionAnonim SınıflarEnum'lar (PHP 8.1)Fiber'lar (PHP 8.1)Nesne Klonlama: Derinlemesine İncelemeGenerator'lar ve Iterator'lar13Tasarım Kalıpları Bölüm 2
Komut KalıbıAdaptör KalıbıDekoratör KalıbıŞablon Metot KalıbıDurum KalıbıKompozit KalıbıRepository Kalıbı2İsim Alanları ve Autoloading
İsim Alanlarına Girişuse Anahtar KelimesiPSR-4 Autoloading StandartıComposer AutoloaderÖzet - Düzenli Proje5Arayüzler ve Sözleşmeler
Arayüzlere GirişArayüzleri UygulamaBirden Fazla Arayüz UygulamaArayüz vs Soyut SınıfArayüzler ile Tip BelirlemeÖzet - Şekil Hesaplayıcı8Sihirli Metotlar
Sihirli Metotlara Giriş__toString & __debugInfo__get, __set, __isset, __unset__call & __callStatic__clone & Nesne Klonlama__serialize & __unserializeÖzet - Özel Koleksiyon3Sınıf Özellikleri
Örnek ve Statik ÖzelliklerSınıflarda SabitlerStatik Metotlar ve ÖzelliklerPrivate ve Protected ÖzelliklerReadonly Özellikler (PHP 8.1)Özet - Banka Hesabı Yöneticisi6Çok Biçimlilik
Metot Geçersiz Kılmaya Yeniden BakışArayüzler ile Çok BiçimlilikType Hinting ve Union TypesLate Static BindingÖzet - Ödeme İşlemcisi9Trait'ler
Trait'lere GirişÇoklu Trait KullanımıTrait Çakışma ÇözümüTrait'lerde Soyut MetotlarTrait'ler ve Kalıtım12Tasarım Kalıpları Bölüm 1
Tasarım Kalıplarına GirişSingleton KalıbıFactory KalıbıObserver KalıbıStrategy Kalıbı15Final Meydan Okumaları
E-Öğrenme PlatformuBankacılık SistemiOyun Karakteri GeliştirmeAraç Kiralama Servisi