Factory Kalıbı
Coddy'nin Java Journey'sinin Nesne Yönelimli Programlama bölümünün bir parçası — ders 66 / 87.
Factory Pattern (Fabrika Deseni), nesne oluşturma işlemini ayrı bir metoda veya sınıfa devreden kurucu (creational) bir tasarım desenidir. Kodunuzda doğrudan new kullanmak yerine, nesneleri sizin için oluşturması için bir fabrikadan istersiniz. Bu, ortak bir arayüzü veya üst sınıfı paylaşan birden fazla ilişkili sınıfınız olduğunda özellikle yararlıdır.
E-posta, SMS veya anlık bildirimler gönderebilen bir bildirim sistemi düşünün. Bir fabrika (factory) olmadan, kodunuzun her bir somut sınıfı bilmesi gerekir:
// Fabrika Olmadan - istemci tüm somut sınıfları bilmelidir
Notification notification;
if (type.equals("email")) {
notification = new EmailNotification();
} else if (type.equals("sms")) {
notification = new SMSNotification();
}Factory Pattern (Fabrika Deseni) ile bu oluşturma mantığını merkezileştirirsiniz:
public interface Notification {
void send(String message);
}
public class EmailNotification implements Notification {
public void send(String message) {
System.out.println("Email: " + message);
}
}
public class SMSNotification implements Notification {
public void send(String message) {
System.out.println("SMS: " + message);
}
}
public class NotificationFactory {
public static Notification create(String type) {
if (type.equals("email")) {
return new EmailNotification();
} else if (type.equals("sms")) {
return new SMSNotification();
}
return null;
}
}Artık istemci kodu daha temiz ve somut sınıflara bağımlı değil:
Notification notification = NotificationFactory.create("email");
notification.send("Hello!"); // Çıktı: Email: Hello!Temel avantaj, yeni bildirim türleri eklemenin yalnızca fabrikayı (factory) güncellemeyi gerektirmesi ve istemci kodunun (client code) değişmeden kalmasıdır. Bu, bir arayüze (interface) göre programlama ilkesini takip ederek sisteminizi daha esnek ve genişletilmesi daha kolay hale getirir.
Görev
KolayFactory Pattern kullanarak bir şekil çizme sistemi oluşturalım! Kodunuzun her yerinde doğrudan şekil nesneleri oluşturmak yerine, oluşturma mantığını basit bir dize tanımlayıcısına dayalı olarak farklı şekil türleri üreten bir fabrikada merkezileştireceksiniz.
Kodunuzu dört dosya halinde düzenleyeceksiniz:
Shape.java: Tüm şekiller için ortak bir sözleşme görevi görenShapeadında bir arayüz (interface) tanımlayın. Arayüzünüz, hiçbir şey döndürmeyen ancak çizilen şekil hakkında bilgi yazdıran tek birdraw()yöntemi bildirmelidir.Shapes.java:Shapearayüzünüzü uygulayan üç sınıf oluşturun:Circle-draw()yöntemiDrawing a CircleyazdırmalıdırRectangle-draw()yöntemiDrawing a RectangleyazdırmalıdırTriangle-draw()yöntemiDrawing a TriangleyazdırmalıdırShapeFactory.java: Şekil oluşturma işlemini gerçekleştiren fabrika sınıfını oluşturun.ShapeFactorysınıfınız, birShapedöndüren statik bircreateShape(String type)yöntemine sahip olmalıdır. type parametresine bağlı olarak:- Eğer type
"circle"değerine eşitse, yeni birCircledöndürün - Eğer type
"rectangle"değerine eşitse, yeni birRectangledöndürün - Eğer type
"triangle"değerine eşitse, yeni birTriangledöndürün - Diğer tüm değerler için
nulldöndürün
- Eğer type
Main.java: Fabrika sisteminizi bir araya getirin! İki girdi alacaksınız: iki şekil türü (her ikisi de String).Her girdi için, şekli oluşturmak üzere
ShapeFactorysınıfınızı kullanın ve bunu birShapedeğişkeninde saklayın. Eğer fabrika geçerli bir şekil döndürürse (null değilse), onundraw()yöntemini çağırın. Eğer null döndürürse, [type] sağlanan girdi olmak üzereUnknown shape: [type]yazdırın.Her iki girdiyi de sırayla, her biri kendi çıktı satırında olacak şekilde işleyin.
Sırasıyla iki girdi alacaksınız: birinci şekil türü (String) ve ikinci şekil türü (String).
Main sınıfınızın hiçbir zaman doğrudan new Circle() veya new Rectangle() kullanmadığına dikkat edin; yalnızca Shape arayüzünü bilir ve fabrikadan nesneler oluşturmasını ister. Factory Pattern'in gücü budur: istemci kodu somut sınıflardan ayrıştırılır!
Kopya kağıdı
Factory Pattern (Fabrika Deseni), nesne oluşturma işlemini ayrı bir metoda veya sınıfa devreden, oluşturma mantığını merkezileştiren ve istemci kodunu somut uygulamalardan ayıran bir kurucu (creational) tasarım desenidir.
Nesneleri doğrudan new ile örneklemek yerine, bir fabrika metodu kullanırsınız:
// Factory olmadan - istemci somut sınıflara bağımlıdır
Notification notification;
if (type.equals("email")) {
notification = new EmailNotification();
} else if (type.equals("sms")) {
notification = new SMSNotification();
}Factory Pattern ile ortak bir arayüz ve somut uygulamalar tanımlayın:
public interface Notification {
void send(String message);
}
public class EmailNotification implements Notification {
public void send(String message) {
System.out.println("Email: " + message);
}
}
public class SMSNotification implements Notification {
public void send(String message) {
System.out.println("SMS: " + message);
}
}Statik bir oluşturma metoduna sahip bir fabrika sınıfı oluşturun:
public class NotificationFactory {
public static Notification create(String type) {
if (type.equals("email")) {
return new EmailNotification();
} else if (type.equals("sms")) {
return new SMSNotification();
}
return null;
}
}İstemci kodu, doğrudan örnekleme yerine fabrikayı kullanır:
Notification notification = NotificationFactory.create("email");
notification.send("Hello!"); // Çıktı: Email: Hello!Avantajları: Yeni türler eklemek sadece fabrikayı güncellemeyi gerektirir; istemci kodu değişmeden kalır. Bu, bir arayüze göre programlama prensibini takip ederek sistemleri daha esnek ve genişletilmesi daha kolay hale getirir.
Kendin dene
import java.util.Scanner;
class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
// İki şekil türünü oku
String type1 = scanner.nextLine();
String type2 = scanner.nextLine();
// TODO: İlk şekli oluşturmak için ShapeFactory kullan
// Eğer şekil null değilse, draw() metodunu çağır
// Eğer şekil null ise, "Unknown shape: [type]" yazdır
// TODO: İkinci şekil için aynısını yap
}
}
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 Nesnelerthis Anahtar KelimesiMetotlarAlanlar (Öznitelikler)Yapıcı MetotYapıcı Metot Aşırı YüklemeÖzet - Basit Hesap Makinesi4Kalıtım
Temel Kalıtım (extends)super Anahtar KelimesiMetot Geçersiz Kılma (@Override)Yapıcı Metot ZincirlemeObject SınıfıTekli ve Çok Seviyeli KalıtımNeden Çoklu Sınıf Kalıtımı Yok?Özet - Çalışan Hiyerarşisi7Özel Metotlar ve Object Sınıfı
toString() Metoduequals() ve hashCode()clone() MetoducompareTo() ve ComparableComparator ArayüzüÖzet - Özel Sıralama2Erişim Belirleyiciler ve Kapsülleme
Erişim Seviyelerine Genel BakışGetter ve Setter MetotlarıBilgi Gizlemefinal Anahtar KelimesiÖzet - Banka Hesabı Yöneticisi5Polimorfizm
Metot Aşırı Yükleme TemelleriMetot Geçersiz Kılma (Çalışma Zamanı)Upcasting ve Downcastinginstanceof OperatörüSoyut Sınıflar ve MetotlarÖzet - Şekil Hesaplayıcı8İleri Düzey OOP Kavramları
Kompozisyon vs KalıtımAgregasyon vs KompozisyonDahili, Yuvalanmış ve Anonim SınıflarEnum'lar ve Enum MetotlarıRecords (Java 16+)Sealed Classes (Java 17+)11Tasarım Kalıpları Bölüm 1
Tasarım Kalıplarına GirişSingleton KalıbıFactory KalıbıBuilder KalıbıObserver KalıbıStrategy Kalıbı14Final Meydan Okumaları
E-Öğrenme PlatformuBankacılık SistemiOyun Karakteri GeliştirmeAraç Kiralama Servisi3Sınıf Özellikleri ve Statik Üyeler
Instance ve Statik DeğişkenlerStatik MetotlarStatik BloklarSabitler (static final)Özet - Sayaç ve Utility6Arayüzler ve Soyut Sınıflar
Arayüzlere GirişArayüzleri UygulamaÇoklu Arayüz UygulamaArayüzlerde Default ve StaticSoyut Sınıflar ve ArayüzlerFonksiyonel ArayüzlerÖzet - Ödeme Sistemi9Generics
Generics'e GirişGeneric SınıflarGeneric MetotlarSınırlandırılmış Tip ParametreleriWildcard'lar (?, extends, super)Özet - Generic Container12Tasarı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ıYineleyici Kalıbı