Temel mantık birbirine benzer nesnelerin aynı arayüzden türetilerek oluşturulmasıdır. Bununla beraber sınıflar bir arayüzden tanımlandığı için gevşek bağlılık prensibini de yerine getirmiş olur.

Genel olarak kullanım şekli isteği gönderen istemcinin gönderdiği isteğe göre sonucu döndürebilecek yapının çalışma zamanında oluşturulmasıdır. İşin püf noktası zaten burada gizli “istemciden gelen bilgiye göre yapının oluşturulması”.
Bu tasarım deseni bilgisine ve pratiğine sahip olmayan yazılım geliştiriciler, içinde gelen isteğe göre bolca oluşturulmuş if blokları bulunan sınıfları yazar ve hala da yazmaya devam ederler. Sınıfın içinde yüzlerce kod satırı görürüz. Bunun yanında open close prensibine de uygun olmayan bir sınıf ortaya çıkar. İstek içinde bulunan parametlere bir yenisi eklendiğinde yüzlerce belki binlerce satır içinde geliştirme yapmaya ve kaybolmaya başlarlar.
Kötü kod örneklerini defalarca görmüşüzdür, şimdi bu işi Factory Pattern ile yapalım.
Örnek sıkça verilen bir örnek olan ödeme yöntemleri olacak.
Üç farklı ödeme yöntemimiz var:
- Kredi Kartı
- Kapıda Ödeme
- Havale
İstemcinin gönderdiği ödeme türüne göre yapımız o ödeme metodunu oluşturup işlemi gerçekleştirecek.
Şimdi bu bağımlılıkları soyutlamamız gerekiyor. Bunun için her sınıfın ortak ihtiyaç duyduğu metodu içeren bir interface (arayüz) tanımlamamız gerekir ve bu ödeme yöntemlerinin hepsinin zaten ortak noktası ödeme yapmak.
O zaman gelin aşağıdaki gibi bir interface tanımlayalım :
public interface IPaymentMethod
{
void Pay(decimal amount);
}
Şimdi bu arayüzü uygulayacak olan sınıflarımızı oluşturalım :
public class CreditCardPayment : IPaymentMethod
{
public void Pay(decimal amount)
{
Console.WriteLine($"Kredi kartıyla {amount:C} ödeme yapıldı.");
}
}
public class BankTransferPayment : IPaymentMethod
{
public void Pay(decimal amount)
{
Console.WriteLine($"Havale ile {amount:C} ödeme yapıldı.");
}
}
public class CashOnDeliveryPayment : IPaymentMethod
{
public void Pay(decimal amount)
{
Console.WriteLine($"Kapıda {amount:C} ödeme yapılacak.");
}
}
Şimdi istemcinin bize göndereceği ve bizim gelen ödeme tipini ayırt edebileceğimiz ödeme tiplerini barındırınan bir enum oluşturalım :
public enum PaymentType
{
CreditCard,
BankTransfer,
CashOnDelivery
}
Şimdi artık factory sınıfımızı yazabiliriz :
public static class PaymentFactory
{
public static IPaymentMethod CreatePaymentMethod(PaymentType paymentType)
{
return paymentType switch
{
PaymentType.CreditCard => new CreditCardPayment(),
PaymentType.BankTransfer => new BankTransferPayment(),
PaymentType.CashOnDelivery => new CashOnDeliveryPayment(),
_ => throw new NotImplementedException("Bilinmeyen ödeme yöntemi")
};
}
}
Şimdi artık bu yapımızı kullanmak için bir OrderService oluşturalım :
public class OrderService
{
public void ProcessOrder(decimal totalAmount, PaymentType paymentType)
{
IPaymentMethod payment = PaymentFactory.CreatePaymentMethod(paymentType);
payment.Pay(totalAmount);
}
}
Ve konsoldan uygulayalım :
class Program
{
static void Main()
{
var orderService = new OrderService();
orderService.ProcessOrder(250.75m, PaymentType.CreditCard);
orderService.ProcessOrder(180.00m, PaymentType.BankTransfer);
orderService.ProcessOrder(99.99m, PaymentType.CashOnDelivery);
}
}
İşte bu sayede yeni bir ödeme tipi eklemek daha da kolaylaştı, Yeni ödeme türüiçin sadece IPaymentMethod implementasyonu ve factory update. Servis sınıfınız if-else veya switch-case ile boğulmaz , sadece factory’de olur. Dependency Injection’a da kolay entegre olur.
Bir yanıt yazın