C# Factory Method Pattern Kullanımı - OOP Design Patterns
Nesne yaratımını kalıtım yoluyla alt sınıflara bırakarak, client tarafında nesne yaratımını engellemektir. Yani Factory Pattern arayüzle nesne yaratım işlemlerini birbirinden ayırır. Bu bize nasıl yardımcı olur diye düşünürsek örneğin bir class yarattık ve bu class belli bir business logic ile yaratılması gerekiyor. Bu class'ın yaratılma işini client'a bırakmak istemeyiz çünkü yanlış tanımlaması programın düzgün çalışmasını engelleyecektir.
Fakat bu yazımda bazı sorunlar var:
- İleride bir ihtiyaç oldu ve programa yeni bir arac eklenmesi gerekti bu durumda client'a kodunu değiştirmesini istiyeceğiz. Client'ı bir müşteri olarak düşünün yeni bir araç geldi müşteriye gidip kodunuza şunu ekler misiniz diyeceksiniz böyle bir durumda.
- Nesne oluşturma işini client'a bıraktık bunu kontrol edemiyoruz. Client kodu yalnış yazıp Bisiklet girildiğinde araba nesnesi oluşturabilir.
Bu tip sorunları ortadan kaldırmak için Factory Pattern kullanabiliriz.
Bu sorunun çözümü için ISecim diye bir interface yaratıp. Bisiklet ve Araba nesnelerini bu interface'ten türetebiliriz. Sonrasında ise bir factory class üzerinden ISecim tipinde nesne yaratan seciliObjeyiYarat fonksiyonu ile kullanıcı tarafından girilen bilgiye göre nesne yaratabiliriz. Bu durumda yukarda saydığım iki sorunda çözülmüş olur. Bu şekilde yazdığımızda örneğimiz şu şekilde olacaktır:
Class tasarımımızı böyle yaptıktan sonra artık clientin işini iyice kolaylaştırmış olduk. Çünkü artık kendisinin bir kontrol yapmasına gerek kalmadı bu sayede de biz yaratılan nesnenin doğruluğundan emin olduk. Son halde client'ın yazması gereken kod şu şekilde:
Aynı zamanda bu pattern'ı kullanmamız programda bir değişiklik olduğunda client tarafında değişikliğe gidilmemesini sağlar. Bu programlamada önemli bir konudur. Çünkü client tarafına minimum değişiklik hedeflenmelidir bu sayede hata kontrolüde daha iyi olacaktır.
Çok basit bir örnekle bir araç seçimi yapılan bir program düşünelim. Kullanıcı ekrandan araç tipini yazıyor ve client bu bilgiyi kullanarak eğer "araba" girilmişse araba nesnesini "bisiklet" girilirse bisiklet nesnesini yaratıyor. İlk aklımıza gelen program şu şekilde olur herhalde:
//
kullanici arac tercihini giriyor
//
if (secim == "Araba")
{
//
eger araba girildiyse araba nesnesi yarat
clsAraba a = new clsAraba();
a.SatinAl();
}
if (secim == "Bisiklet")
{
//
eger bisiklet girildiyse bisiklet nesnesi yarat
clsBisiklet b = new clsBisiklet();
b.SatinAl();
}
Fakat bu yazımda bazı sorunlar var:
- İleride bir ihtiyaç oldu ve programa yeni bir arac eklenmesi gerekti bu durumda client'a kodunu değiştirmesini istiyeceğiz. Client'ı bir müşteri olarak düşünün yeni bir araç geldi müşteriye gidip kodunuza şunu ekler misiniz diyeceksiniz böyle bir durumda.
- Nesne oluşturma işini client'a bıraktık bunu kontrol edemiyoruz. Client kodu yalnış yazıp Bisiklet girildiğinde araba nesnesi oluşturabilir.
Bu tip sorunları ortadan kaldırmak için Factory Pattern kullanabiliriz.
Bu sorunun çözümü için ISecim diye bir interface yaratıp. Bisiklet ve Araba nesnelerini bu interface'ten türetebiliriz. Sonrasında ise bir factory class üzerinden ISecim tipinde nesne yaratan seciliObjeyiYarat fonksiyonu ile kullanıcı tarafından girilen bilgiye göre nesne yaratabiliriz. Bu durumda yukarda saydığım iki sorunda çözülmüş olur. Bu şekilde yazdığımızda örneğimiz şu şekilde olacaktır:
//
//
Interface
//
public interface ISecim
{
string SatinAl();
}
//
//
Factory Class
//
public class FactorySecim
{
static public ISecim seciliObjeyiYarat(string secim)
{
ISecim objSecim = null;
if (secim.ToLower() == "araba")
{
objSecim = new clsAraba();
}
else if (secim.ToLower() == "bisiklet")
{
objSecim = new clsBisiklet();
}
return objSecim;
}
}
//Business
classes
//Bisiklet
public class clsBisiklet : ISecim
{
#region
ISecim Elemenlari
public string SatinAl()
{
return ("Bisiklet sectiniz.");
}
#endregion
}
//Araba
public class clsAraba : ISecim
{
#region
ISecim Elemenlari
public string SatinAl()
{
return ("Araba sectiniz.");
}
#endregion
}
Class tasarımımızı böyle yaptıktan sonra artık clientin işini iyice kolaylaştırmış olduk. Çünkü artık kendisinin bir kontrol yapmasına gerek kalmadı bu sayede de biz yaratılan nesnenin doğruluğundan emin olduk. Son halde client'ın yazması gereken kod şu şekilde:
//Client
class
ISecim objInvoice;
objInvoice = FactorySecim.seciliObjeyiYarat(txtChoice.Text.Trim());
MessageBox.Show(objInvoice.SatinAl());
FactorySecim içindeki seciliObjeyiYarat methodu OCP(Open Closed Responsibility) ye ters olmuş. Bunun onune geçmek için Strategy Design pattern aracılığıyla cozulebilir. FactorySecim i Abstract bir class yapıp,seciliObjeyiYarat methodu abstract tanımlayıp bisiklet ve arabayı bunlardan tureyen class şeklinde yapılırsa cuk oturur. Cok faydalı paylaşım. eline sağlık
YanıtlaSil