|
Abstract Factory Tasarım Deseni(Design Pattern) |
|
Gönderiliyor lütfen bekleyin... |
|
|
Singleton
deseni ile başladığım "design pattern" yazı dizisine "Abstract
Factory" deseni ile devam ediyoruz. Bu yazıda "Creational" desenler
grubunun en önemli ve en sık kullanılan deseni olan Abstract Factory(Soyut Fabrika)
tasarım deseninin C# ile ne şekilde uygulandığını bir örnek üzerinden göstereceğim.
İlk yazımda da bahsettiğim gibi "Creational" grubundaki desenler bir
yada daha çok nesnenin çeşitli şekillerde oluşturulması ile ilgili desenlerdir.
Bu kategoride ele alınan "Abstract Factory" ise birbirleriyle ilişkili
yada birbirlerine bağlı olan nesnelerin oluşturulmasını en etkin bir şekilde
çözmeyi hedefler. Bu hedefe ulaşmak için soyut sınıflardan(abstract class) veya
arayüzlerden(interface) yoğun bir şekilde faydalanmaktadır. "Abstract Factory"
deseninin ana teması belirli sınıfların içerdiği ortak arayüzü soyut bir sınıf
yada arayüz olarak tasarlamaktır. Böylece nesneleri üreten sınıf, hangi nesnenin
üretileceği ile pek fazla ilgilinmesi gerekmez. İlgilenmesi gereken nokta oluşturacağı
nesnenin hangi arayüzleri desteklediği yada uyguladığıdır. Bahsi geçen mekanizmalarla
deseni oluşturduğumuz anda çalışma zamanında hangi nesnenin oluşturulması gerektiğini
bilmeden nesnelerin oluşturulmasını yönetebiliriz.
Eğer bir nesne oluşturacaksanız ve tam olarak hangi nesnenin oluşturulacağına
bir switch yada if deyimi ile karar veriyorsanız muhtemelen her nesneyi oluştruduğunuzda
aynı switch yapısını kullanmak zorunda kalacaksınız. Bu tür tekrarları önlemek
için "Abstarct Factory" deseninden faydalanılabilir. Bu elbetteki
nesnelerin ortak bir arayüzü uygulamış olma zorunluluğunun getirdiği bir faydadır.
Şimdi de gerçek
dünyadan bir örnek vererek "Abstract Factory" deseninin hangi durumlarda
kullanabileceğimizi ve soyut fabrika mantığını netleştirelim. Bir CD sürücüsü
düşünün. CD sürücüsü kendisine sürülen CD leri okumakla sorumludur. Hiç bir
zaman sürülen CD nin şekli ve biçimiyle ilgilenmez. Ama sürülen CD nin okunabilmesi
için de belirli şartların yerine getirildiğini farzeder. Yani siz CD sürücüsüne
CD olmayan ama CD ye benzeyen bir cisim yerleştiriseniz onu da okumaya çalışır.(eğer
CD sürücünüz bozulmazsa!) Çünkü okumaya çalıştığı cismin ne olduğu ile pek ilgilenmez
CD sürücüsü. Buradaki örnekte CD sürücüsünün okuma yapabilmesi için gereken
şartları bir soyut fabrika sınıfı ile modelleyebiliriz. Kare yada daire şeklindeki
gerçek CD ler ise bu soyut fabrika sınıfı tarafından belirlenen şartları destekleyen
gerçek nesnelerdir. CD sürücüsünün kendisi ise soyut fabrika tarafından belirlenen
standartlar çerçevesi içerisinde CD nin ne tür bir CD olduğundan bağımsız bir
şekilde bilgiyi okuyan birimdir. Bu, "abstract factory" desenindeki
client yani istemci sınıfa denk düşer ki bu sınıf nesnelerin yaratılmasından
sorumludur.
Bu giriş bilgilerinden
sonra "abstract factory" deseninin temel özelliklerini kısaca özetleyelim.
- "Abstract
Factory", nesneleri oluşturan bir sınıftır. Oluşturulan bu nesneler birbirleriyle
ilişkili olan nesnelerdir. Diğer bir deyişle aynı arayüzü uygulamış olan nesnelerdir.
- Üretilen nesnelerin
kendisiyle ilgilenilmez. İlgilenilen nokta oluşturulacak nesnelerin sağladığı
arayüzlerdir. Dolayısıyla aynı arayüzü uygulayan yeni nesneleri desene eklemek
çok kolay ve esnektir.
- Bu desende üretilecek
nesnelerin birbirleriyle ilişkili olması beklenir.
UML
Modeli
Aşağıdaki şekil
"abstract factory" tasarım deseninin yapısal UML diagramını göstermektedir.
Şemadaki her bir şekil desendeki bir sınıfı modellemektedir. Ayrıca desendeki
sınıflar arasındaki ilişkilerde detaylı bir şekilde gösterilmiştir.
Yukarıda şemayı kısaca açıklamakta fayda var. Şemadan da görüleceği üzere "abstract
factory" deseninde 3 ana yapı vardır. İlk yapı nesnelerin oluşturulmasından
sorumlu soyut ve gerçek fabrikalar, ikinci yapı soyut fabrikadan türeyen gerçek
fabrikaların ürettiği ürünleri temsil eden soyut ve gerçek ürün sınıflar, son
yapı ise herhangi bir ürünü, kendisine parametre olarak verilen soyut fabrikaları
kullanarak üreten istemci(client) sınıfıdır.
SoyutFabrika sınıfı gerçek fabrikaların uygulaması gereken arayüzü temsil eder.
Bu sınıf, bütün metotları soyut olan sınıf olabileceği gibi bir arayüz de olabilir.
Uygulamanızın ihtiyacına göre dilediğinizi kullanabilirsiniz. SoyutFabrika sınıfında
ürün1 ve ürün2'nin üretilmesinden sorumlu iki tane metot bulunmaktadır. Dolayısıyla
bütün gerçek fabrikaların hem ürün1'i hemde ürün'yi ürettiği kabul edilmektedir.
Her bir ürünün ortak özelliklerini belirlemek ve ana yapıda toplamak için SoyutUrun1
ve SoyutUrun2 sınıfları oluşturulur. Bu sınıflarda herhangi bir ürüne özel bilgi
bulunmamaktadır. Asıl bilgi bu soyut ürünlerden türeyen GercekUrun sınıflarında
bulunmaktadır. Her bir fabrikanın ürettiği ürünleri modelleyen sınıflarda yukarıdaki
şekilde gösterilmiştir. Asıl önemli mesele ise gerçek fabrikaların üretimden
sorumlu metotlarının ne şekilde geri döneceğidir. Yukarıdaki şemadan da görüleceği
üzere bu metotlar üreteceği ürünün soyut sınıfına dönmektedir. Yani üretim sonucunda
geri dönen gerçek ürün nesnesi değildir. Şemada Client olarak gösterilen sınıfın
yapısı ise şu şekildedir : Client sınıfı yapıcı metoduna bir soyut fabrika nesnesi
alır. Ve soyut fabrikanın üretimden sorumlu metotlarını kullanarak soyut ürünleri
üretir. Dikkat ederseniz Client sınıfı hangi gerçek fabrikanın üretim yaptığından
ve üretilen ürünün gerçek özelliklerinden haberi yoktur. Client sadece soyut
fabrikanın içerdiği temel özelliklerin farkındadır. Bunu şemadaki kalın ve kesikli
oklardan görmek mümkündür.
Desenin
C# ile Gerçekleştirilmesi
Yukarıdaki yapısal
örneği verdikten sonra gerçek bir örnek ile bu deseni nasıl gerçekleştirebileceğimizi
inceleyelim. Bu örnekte araba kasası ve araba lastiği üreten farklı iki firmanın
üretimi modellenmektedir.
Önce örneği kabaca inceleyin, ardından açıklamaları okuyun.
using
System;
namespace
DesignPattern
{
abstract class SoyutArabaFabrikasi
{
abstract
public SoyutArabaKasasi KasaUret();
abstract
public SoyutArabaLastigi LastikUret();
}
class
MercedesFabrikasi : SoyutArabaFabrikasi
{
public
override SoyutArabaKasasi KasaUret()
{
return
new MercedesE200();
}
public
override SoyutArabaLastigi LastikUret()
{
return
new MercedesLastik();
}
}
class
FordFabrikasi : SoyutArabaFabrikasi
{
public
override SoyutArabaKasasi KasaUret()
{
return
new FordFocus();
}
public
override SoyutArabaLastigi LastikUret()
{
return
new FordLastik();
}
}
abstract
class SoyutArabaKasasi
{
abstract
public void LastikTak(SoyutArabaLastigi a );
}
abstract
class SoyutArabaLastigi
{
}
class MercedesE200
: SoyutArabaKasasi
{
public
override void LastikTak(SoyutArabaLastigi lastik)
{
Console.WriteLine(
lastik + " lastikli MercedesE200");
}
}
class FordFocus :
SoyutArabaKasasi
{
public
override void LastikTak(SoyutArabaLastigi lastik)
{
Console.WriteLine(
lastik + " lastikli FordFocus");
}
}
class MercedesLastik
: SoyutArabaLastigi
{
}
class
FordLastik : SoyutArabaLastigi
{
}
class
FabrikaOtomasyon
{
private
SoyutArabaKasasi ArabaKasasi;
private
SoyutArabaLastigi ArabaLastigi;
public
FabrikaOtomasyon( SoyutArabaFabrikasi fabrika )
{
ArabaKasasi
= fabrika.KasaUret();
ArabaLastigi
= fabrika.LastikUret();
}
public
void LastikTak()
{
ArabaKasasi.LastikTak(
ArabaLastigi );
}
}
class
UretimBandi
{
public
static void Main()
{
SoyutArabaFabrikasi
fabrika1 = new MercedesFabrikasi();
FabrikaOtomasyon
fo1 = new FabrikaOtomasyon( fabrika1 );
fo1.LastikTak();
SoyutArabaFabrikasi
fabrika2 = new FordFabrikasi();
FabrikaOtomasyon
fo2 = new FabrikaOtomasyon( fabrika2 );
fo2.LastikTak();
}
}
}
|
Yukarıdaki örnekte
SoyutArabaFabrikasi sınfı iki metot içermektedir. Bu metotlar SoyutArabaFabrikasi
sınıfından türeyecek sınıfların uygulaması gereken metotlardır. Çünkü metotlar
abstract olarak bildirilmiştir. Bu metotlar gerçek fabrika sınıflarının araba
kasası ve araba lastiği üretmesi gerektiğinin belirtisidir. Zira görüldüğü üzere
SoyutArabaFabrikasi sınıfından türeyen MercedesFabrikasi ve FordFabrikasi kendilerine
has lastikleri ve kasaları üretmek için soyut fabrika sınıfının metotlarını kullanmaktadır.
Bu metotlar geri dönüş değeri olarak soyut ürün sınıflarını temsil eden sınıfları
döndürmektedirler. Örneğin KasaUret() metodu her bir fabrika için farklı ürün
üretmesine rağmen her bir ürün SoyutArabaKasasi sınıfındaki metotları uyguladığı
için gerçek ürünler birbirleyile ilişkili hale gelir. Mercedes fabrikası KasaUret()
metodu ile MercedesE200 ürününü döndürmesine rağmen Ford fabrikası aynı metotla
FordFocus ürününü döndürmektedir. Ancak her iki fabrikanın da ürettiği ürün SoyutArabaKasasi
sınıfından türediği için herhangi bir çelişki olmamaktadır.
SoyutArabaKasasi sınıfındaki LastikTak() sınıfı fabrikadan üretilen ürünlerin
birbirleriyle karıştırılmadan esnek bir şekilde nasıl ilişkilendirildiğini gösterilmektedir.
Bu metot parametre olarak gerçek lastik ürünü yerine soyut lastik ürünü alır.
Dolayısıyla herhangi bir fabrikadan üretilen lastik ürünü bu metoda parametre
olarak geçirilebilir.
FabrikaOtomasyon sınıfı kendisine verilen bir soyut fabrika nesnesi üzerinden
kasa ve lastik üretir ve üretilen lastiği, lastiğin gerçek türünü bilmeden üretilen
araba kasası ile ilişkilendirir. Dikkat ederseniz bu sınıf üretimin yapılacağı
fabrikanın hangi fabrika olduğu ve üretilen ürünlerin gerçekte hangi ürünler olduğu
ile ilgilenmez.
Son olarak tasarladığımız bütün bu sınıfları test edecek UretimBandı sınıfını
inceleyelim. Bu sınıf içerisinde ürünleri üretilecek fabrikanın soyut nesnesi
oluşturulur ve FabrikaOtomasyonu nesnesine parametre olarak verilir. SoyutFabrika
nesnesini alan FabrikaOtomasyonu bu nesnenin standart üretimden sorumlu metotlarını
kullanarak kasa ve lastik üretir. Ardından SoyutArabaKasasi sınıfının LastikTak()
metodunu kullanarak kasa ve lastik ürünlerini ilişkilendirir.
Bu örnekte kullanılan soyut sınıfların yerine arayüzleride kullanmak mümkündür.
Daha önce de dediğim gibi siz uygulamanızın durumuna göre herhangi birini seçebilirsiniz.
Diğer bir "Creational" deseni olan "Builder" desenini anlatacağım
yazıda görüşmek üzere...
Makale:
Abstract Factory Tasarım Deseni(Design Pattern) C#, Visual C# ve .NET Sefer Algan
|
|
|
-
-
Eklenen Son 10
-
Bu Konuda Geçmiş 10
Bu Konuda Yazılmış Yazılmış 10 Makale Yükleniyor
Son Eklenen 10 Makale Yükleniyor
Bu Konuda Yazılmış Geçmiş Makaleler Yükleniyor
|
|