Factory Pattern (Fabrika Tasarım Kalıbı), nesne oluşturma sürecini soyutlamak ve istemci kodun doğrudan nesne oluşturmasını engellemek için kullanılan bir oluşumsal tasarım deseni (creational design pattern)dir. Bu desen, bir sınıfın doğrudan new
operatörü ile örneklenmesini engelleyerek, nesne oluşturma sürecini merkezi bir noktada toplar.
Ne Zaman Kullanılmalıdır?
Factory Pattern şu durumlarda kullanışlıdır:
Nesne oluşturma sürecini merkezi hale getirmek:
- Uygulama içinde farklı nesnelerin oluşturulmasını tek bir yerden kontrol etmek.
Gelecekteki değişiklikleri kolaylaştırmak:
- Yeni türler eklendiğinde istemci kodu değiştirmeden nesne üretimini genişletmek.
Soyutlamayı artırmak:
- İstemci kodun alt sınıfların (subclasses) ayrıntılarını bilmesine gerek kalmadan nesne oluşturmasını sağlamak.
Kodun daha modüler olmasını sağlamak:
- Nesne oluşturma süreçlerini merkezi bir noktada yöneterek kod tekrarını önlemek.
Factory Pattern'in Avantajları:
- Gevşek bağlılık (Loose Coupling): Nesne oluşturma sürecinin soyutlanması, bağımlılıkları azaltır.
- Kolay bakım (Maintainability): Yeni nesne türleri eklemek için mevcut kodu değiştirmek gerekmez.
- Kod tekrarını önler: Tek bir fabrika sınıfı üzerinden nesne üretimi yapılır.
Factory Pattern'in Dezavantajları:
- Daha karmaşık kod yapısı: Factory Pattern, basit nesne oluşturma işlemlerine kıyasla daha fazla sınıf içerebilir.
- Performans kaybı: Nesne oluşturma sırasında ek bir soyutlama katmanı eklenir.
1. Basit Factory (Simple Factory)
class ShapeFactory {
public static Shape getShape(String type) {
if (type.equalsIgnoreCase("Circle")) {
return new Circle();
} else if (type.equalsIgnoreCase("Rectangle")) {
return new Rectangle();
}
return null;
}
}
interface Shape {
void draw();
}
class Circle implements Shape {
public void draw() {
System.out.println("Daire çiziliyor");
}
}
class Rectangle implements Shape {
public void draw() {
System.out.println("Dikdörtgen çiziliyor");
}
}
// Kullanım
public class Main {
public static void main(String[] args) {
Shape shape1 = ShapeFactory.getShape("Circle");
shape1.draw();
Shape shape2 = ShapeFactory.getShape("Rectangle");
shape2.draw();
}
}
2. Factory Method Pattern
abstract class ShapeFactory {
abstract Shape createShape();
}
class CircleFactory extends ShapeFactory {
public Shape createShape() {
return new Circle();
}
}
class RectangleFactory extends ShapeFactory {
public Shape createShape() {
return new Rectangle();
}
}
// Kullanım
public class Main {
public static void main(String[] args) {
ShapeFactory factory1 = new CircleFactory();
Shape shape1 = factory1.createShape();
shape1.draw();
ShapeFactory factory2 = new RectangleFactory();
Shape shape2 = factory2.createShape();
shape2.draw();
}
}
3. Abstract Factory Pattern
interface Shape {
void draw();
}
class Circle implements Shape {
public void draw() {
System.out.println("Daire çiziliyor");
}
}
class Rectangle implements Shape {
public void draw() {
System.out.println("Dikdörtgen çiziliyor");
}
}
interface ShapeFactory {
Shape createShape();
}
class CircleFactory implements ShapeFactory {
public Shape createShape() {
return new Circle();
}
}
class RectangleFactory implements ShapeFactory {
public Shape createShape() {
return new Rectangle();
}
}
class FactoryProducer {
public static ShapeFactory getFactory(String type) {
if (type.equalsIgnoreCase("Circle")) {
return new CircleFactory();
} else if (type.equalsIgnoreCase("Rectangle")) {
return new RectangleFactory();
}
return null;
}
}
// Kullanım
public class Main {
public static void main(String[] args) {
ShapeFactory shapeFactory = FactoryProducer.getFactory("Circle");
Shape shape = shapeFactory.createShape();
shape.draw();
}
}
Banka Kartı Üretim Sistemciği
interface Card {
void getType();
}
class CreditCard implements Card {
public void getType() {
System.out.println("Kredi Kartı oluşturuldu");
}
}
class DebitCard implements Card {
public void getType() {
System.out.println("Banka Kartı oluşturuldu");
}
}
class CardFactory {
public static Card getCard(String type) {
if (type.equalsIgnoreCase("Credit")) {
return new CreditCard();
} else if (type.equalsIgnoreCase("Debit")) {
return new DebitCard();
}
return null;
}
}
// Kullanım
public class Main {
public static void main(String[] args) {
Card card1 = CardFactory.getCard("Credit");
card1.getType();
Card card2 = CardFactory.getCard("Debit");
card2.getType();
}
}
Sonuç
Factory Design Pattern, nesne oluşturma sürecini soyutlayarak uygulamanın esnekliğini artırır. Kod tekrarını önler, bakımını kolaylaştırır ve genişletilebilirlik sağlar. Özellikle nesne üretiminin sıkça değiştiği ve yönetilmesi gereken büyük ölçekli uygulamalarda sıkça kullanılır.