Factory Design Pattern Nedir ?

DANYAL CAN KAYRAK
4 min readJun 8, 2023

Öncelikle merhabalar, daha önceki yazılarımızda design pattern nedir diyerek çıktığımız bu serüvende bir diğer design pattern (tasarım kalıbı)’ımız Factory Design Pattern.

Factory Design Pattern yazılım geliştirirken çokca kullanılan Creational Patterns (Yaratımsal Kalıplar)’dan birisidir. Bu design pattern adından da anlaşılacağı gibi aslında bir fabrika görevi görüyor bizler için. Yazılım geliştirirken ihtiyacımız olan nesnelerin direkt olarak new anahtar kelimesi ile bizler tarafından oluşturulması yerine nesne oluşturmayı soyutlayarak merkezileştirir. Böylelikle istemciler, nesnelerin nasıl oluşturulduğu veya hangi sınıfa ait olduğu gibi ayrıntılarla uğraşmak zorunda kalmazlar.

Avantajları ve Dezavantajları :

Avantajları:

  • Soyutlama: Factory tasarım deseni, istemcinin somut sınıflarla doğrudan etkileşimde bulunmak yerine, bir arayüz veya soyut bir sınıf üzerinden etkileşimde bulunmasını sağlar. Bu, kodun daha esnek ve genişletilebilir olmasını sağlar, çünkü istemci, nesnelerin gerçek uygulaması hakkında bilgi sahibi olmadan nesneleri kullanabilir.
  • Nesne oluşturma merkezileştirme: Factory tasarım deseni, nesne oluşturma işlemini merkezi bir noktaya taşır. Bu, istemcilerin nesne oluşturma kodunu tekrar etmek zorunda kalmadan yeni nesneler oluşturmasını sağlar. Aynı zamanda nesne oluşturma sürecini daha yönetilebilir hale getirir ve kod tekrarını azaltır.
  • Gelecekteki değişikliklere uyum sağlama: Factory tasarım deseni, kodun gelecekteki değişikliklere uyum sağlamasını kolaylaştırır. Yeni bir nesne türü eklemek veya mevcut bir nesne türünü değiştirmek istediğinizde, sadece Factory sınıfını güncellemeniz yeterli olabilir. İstemci kodunda herhangi bir değişiklik yapmanız gerekmez.

Dezavantajları:

  • Karmaşıklık: Factory tasarım deseni, bir ekstra sınıf (Factory sınıfı) ekleyerek kodun karmaşıklığını artırır. Ekstra sınıfın yönetimi ve sınıflar arası iletişim, projenin karmaşıklığını artırabilir. Basit senaryolarda bu ekstra karmaşıklık gereksiz olabilir.
  • Tek sorumluluk prensibine aykırılık: Factory tasarım deseni, sınıfların tek sorumluluk prensibine aykırı olabilecek şekilde sorumlulukları başka bir sınıfa devreder. Factory sınıfı, birden fazla sınıfın yaratılmasıyla ilgilenir ve bu, sınıfın sorumluluklarının artmasına neden olabilir.
  • Sınıf sayısının artması: Factory tasarım deseni, her bir farklı nesne türü için ayrı bir Factory sınıfı veya yöntemi gerektirebilir. Bu da projede daha fazla sınıfın oluşmasına ve sınıf sayısının artmasına yol açabilir. Sınıf sayısının artması, projenin karmaşıklığını ve bakımını zorlaştırabilir.

Factory tasarım desenini kullanmak veya kullanmamak, proje gereksinimlerine ve tasarım hedeflerine bağlıdır. Desenin avantajları, genel olarak daha esnek ve genişletilebilir bir kod tabanı sağlamak için önemli olabilir. Ancak dezavantajları da dikkate alınmalı ve proje özelliklerine göre değerlendirilmelidir.

Factory Design Pattern Nasıl Uygulanır ?

Uml Diyagramı

Aslında yapmamız gerekenleri şu şekilde adımlara ayırabiliriz :

  1. Abstract veya interface bir sınıf oluşturulur.
  2. Üretilmesi gereken sınıflar interface veya abstract sınıftan türetilir.
  3. Factory (Fabrika) sınıfımızı oluştururuz.
  4. Geriye sadece çağırmak kalıyor :)

Benim fabrika sınıfımda ProductX ve ProductY olmak üzere 2 farklı ürün üreteceğim. O halde başlıyalım.

Adım 1 : IProduct Arayüzünün Oluşturulması

Arayüzümüzde sınıflarımızın içereceği field(alan)’ları ekliyelim.

public interface IProduct {
String getProductName();
double getProductPrice();
}

Adım 2 : Üretilmek İstenen Sınıfların Oluşturulması

ProductX sınıfımızı oluşturuyoruz.

public class ProductX implements IProduct{

private String productName;
private double productPrice;

public ProductX(String productName, double productPrice) {
this.productName = productName;
this.productPrice = productPrice;
}

@Override
public String getProductName() {
return productName;
}

@Override
public double getProductPrice() {
return productPrice;
}

@Override
public String toString() {
return "ProductX{" +
"productName='" + productName + '\'' +
", productPrice=" + productPrice +
'}';
}
}

ProductY sınıfımızı da oluşturuyoruz.

package factoryPattern;

public class ProductY implements IProduct{
private String productName;
private double productPrice;

public ProductY(String productName, double productPrice) {
this.productName = productName;
this.productPrice = productPrice;
}

@Override
public String getProductName() {
return productName;
}

@Override
public double getProductPrice() {
return productPrice;
}

@Override
public String toString() {
return "ProductY{" +
"productName='" + productName + '\'' +
", productPrice=" + productPrice +
'}';
}
}

Yukarıdaki gibi oluşturduğumuz interface’i de sınıflarımıza implement ediyoruz. Oluşturmak istediğimiz nesnenin özelliklerini de constructor(yapıcı)’mız sayesinde alıyoruz. En son olarak toString() metotunu da override ettim. Sınıflarımızın çıktılarını böyle görmek daha kolay geliyor :)

Adım 3: Factory Sınıfının Oluşturulması

public class ProductFactory {
public IProduct createProduct(String productType,String productName,double productPrice){
if(productType.equals("X")){
return new ProductX(productName,productPrice);
}else if(productType.equals("Y")){
return new ProductY(productName,productPrice);
}else{
throw new RuntimeException("Geçersiz Ürün Tipi : "+productType);
}
}
}

Buradaki createProduct metotunu istediğinize ve ihtiyacınıza göre static olarak belirleyebilirsiniz. Yukarıdaki gibi bir logic ile de hangi sınıfı istediğimizi belirtmiş oluyoruz. Eğer istenilenin dışında bir değer gelirse de hata fırlatıyoruz.

Adım 4 : Nesnelerimizi Üretelim

public class Main {
public static void main(String[] args) {

// Fabrikamızı çağırıyoruz
ProductFactory productFactory = new ProductFactory();

// İstediğimiz ürünümüzü fabrikamız vasıtasıyla çağırıyoruz.
IProduct productX = productFactory.createProduct("X","X ürünüm",1500);
IProduct productY = productFactory.createProduct("Y","Y ürünüm",3500);

// Objelerimizi yazdıralım.
System.out.println(productX);
System.out.println(productY);
}
}

Nesnelerimizi istediğimiz yerde yukarıdaki gibi çağırabiliyoruz. Böylelikle new anahtarını kullanmamıza gerek kalmıyor ve nesne üretimini soyut bir şekilde halletmiş oluyoruz.

Çıktımız ise şu şekilde oluyor :

ProductX{productName=’X ürünüm’, productPrice=1500.0}
ProductY{productName=’Y ürünüm’, productPrice=3500.0}

Bu yazımızı da bu şekilde noktalamış oluyoruz. Umarım faydası olmuştur sizler için de :) Ben yazarken öğrenirken bir o kadar da eğlendim :) Bir sonraki yazımızda görüşürüz, takipte kalınız. Sağlıcakla 👋

--

--