Tasarım Kalıpları: Factory Method (Üretici Metot) – I

Factory method ya da Türkçesiyle üretici metot, muhtemelen programcılık tecrübesi içerisinde programcıların tabi olarak ihtiyacını ilk defa hissettikleri kalıptır. Çünkü bu kalıp, nesnelerin yaratılmalarını soyutlamakta ve üretici metot dediğimiz factory metoduna havale etmektedir.

GoF’da bu kalıbın amacı için şu denmektedir:

Intent: Define an interface for creating an object, but let subclasses decide which class to instantiate. Factory Method lets a class defer instantiation to subclasses.

Amaç: Bir nesne yaratmak için bir arayüz tanımla, fakat hangi sınıfın nesnesinin oluşturulacağına alt sınıflar karar versin. Factory methodu bir sınıfın nesne oluşturmasını alt sınıflarına ertelemesine izin verir.

Problem

Nesne-merkezli programlardaki tabi olarak en temel iş, nesne yaratmaktır. Uygulamalarda farklı karmaşıklıkta pek çok sınıf vardır ve bu sınıfların nesneleri uygulamanın farklı yerlerinde oluşturulur. Bu kalıp, nesnelerin yaratılmalarını soyutlamakta ve bu işi “üretici” ya da “factory” metoda havale etmektedir. Factory method, nesnelerin yaratılmasından sorumlu bir metottur öyle ki bir arayüzün alt sınıfında bulunur.

Client’ın, Product nesnelerinin sadece arayüzlerini değil aynı zamanda nasıl yaratılacaklarını da bilmesi, Client’ın Product’lara olan bağımlılığını arttırır. Çoğu zaman bir nesneyi yaratmak, onu kullanmaktan daha karmaşıktır.

Aşağıdaki diyagramda, Client ile Product nesneleri arasında, doğrudan yaratmaya bağlı ilişki ifade edilmiştir.

Klasik Client-Product ilişkisi.

Klasik Client-Product ilişkisi.

Bu duruma karşılık gelen ProductA ve ProductB kodları şöyledir:

package org.javaturk.dp.pattern.gof.creational.factoryMethod.product.old;

public class ProductA {
	private int id;
	private String name;
	
	public ProductA(int id, String name) {
		this.id = id;
		this.name = name;
	}

	public void doThis(){
		System.out.println("do() in ProductA");
	}

	public int getId() {
		return id;
	}
        ...
}

ve

package org.javaturk.dp.pattern.gof.creational.factoryMethod.product.old;

public class ProductB {
	private int no;
	private String description;
	
	public ProductB(int no, String description) {
		this.no = no;
		this.description = description;
	}

	public void doThis(){
		System.out.println("do() in ProductB");
	}

	public int getNo() {
		return no;
	}
	...
}

ve Client da:

package org.javaturk.dp.pattern.gof.creational.factoryMethod.product.old;

public class Client {
	
	private ProductA productA;
	private ProductB productB;
	
	public Client(){
		productA = new ProductA(1, "Product-A-1");
		productB = new ProductB(2, "Product-B-2");
	}
	
	public void start(){
		productA.doThis();
		productB.doThis();
	}
}

 

Çözüm

Bu yüzden Client’ın Product’ları doğrudan yaratmak yerine, bunu üretici metotlara havale etmesi ve Product’larla arayüzleri üzerinden haberleşmesi daha rahattır. Bu ise Factory arayüzünü yerine getiren ve üretici metotlara sahip üretici sınıflarla başarılır. Bu şekilde Client’ın hem Product’lara hem de onları üreten Factory’lere bağımlılığı arayüz seviyesine iner.

Factory method kalıbından sonraki ilişki

Factory method kalıbından sonraki ilişki

 

Bir sonraki yazıda Factory Method ile geliştirdiğimiz çözümün kodlarına bakacağız.

Toplam görüntülenme sayısı: 3814