Yazılım mühendisliğinin sanatsal yönü ağır olan "design
pattern" kavramını bir çoğumuz mutlaka duymuşuzdur, ama rutin işlerimizden
kendimizi boşa çıkarıp bir türlü inceleme fırsatı bulamamışızdır, Bu ve bundan
sonraki bir kaç makalelik dizide size kendi terminolojik yapısı içinde deyimleşmiş
olan "design pattern" yani "desen tasarımı" kavramını açıklamaya
çalışacağım. Elbette açıklamalarımı en çok bilinen tasarım desenleri ile
destekleyeceğim. Bu konudaki ilk makalede en basit ve en popüler tasarım
desenlerinden biri olan "Singleton" deseninden bahsedip "pattern
design" sanatına daha farklı bir bakış açısıyla yaklaşmanızı sağlamaya çalışacağım.
O halde işe basit tanımlarla başlayalım.
"Design Pattern" Nedir ?
Bildiğiniz üzere günümüzde yazılım mühendisliği alanında en fazla ses getiren kurgu yazılımın gerçek dünya ile olan ilişkisinin sağlanabilmesidir. Bu ilişki elbette nesne yönelimli programlama tekniği ile sağlanmaktadır. Nesne yönelimli programlama tekniği bilgisayar uygulamalarını soyut bir olgudan çıkararak insanların daha kolay algılayabileceği hale getirmiştir. Öyle görünüyorki, makro düzeyde gerçek hayatı modelleme ile başlayan bu ilişki mikro düzeydede büyük ses getirecektir. Nitekim son yıllarda geliştirilen yapay sinir ağları ile makinelerin çalışma sistemlerinin gün geçtikçe insanların veya canlıların çalışma şekline yaklaştığı görülmektedir. Artık bilgisayarlardan sadece verilen komutları yerine getirmek değil, belirli olaylar ve durumlar karşısında bazı hükümlere varabilmeleride istenmektedir. Burada vurgulamak istediğim nokta şudur : bizler yazılım mühendisleri veya programcılar olarak gerçek hayatı ne kadar iyi modelleyebiliyorsak o kadar başarılı sayılırız. Peki "desgin pattern" konusu nerede devreye girmektedir? İşte benimde gelmek istediğim nokta budur; "desgin patterns" bir modelin tasarımın ustaca tasarlanmasını sağlayacak çeşitli desenlerin oluşturulmasını ve bu desenlerin ihtiyaç dahilinde herhangi bir modelin inşaasında kullanılabilmesini sağlar. "Design pattern" kavramı bir kurallar topluluğundan ziyade bir işi nasıl ve en güzel ne şekilde yapabileceğimiz gösteren yöntemler topluluğudur. Öyleki iyi bir yazılım modelleyicisiyseniz kendi tasarım desenlerinizi oluşturabilir ve bunları diğer ustaların kullanımına sunabilirsiniz. Tasarım desenleri tecrübe ile oluşturulan yapılardır. Bazıları olmazsa olmaz yapılar olmasına rağmen bazıları tamamen yazılımın sanatsal yönünü göstermek için tasarlanmıştır . Örneğin bu yazımın ana konusunu belirleyen "Singleton" tasarım deseni yıllardan beri bir çok kişi tarafından kullanılmıştır. Sizde bu yazıda bu desenin amacını ve nasıl uygulandığını öğrendiğinizde eminimki projelerinizde mutlaka kullanacaksınız. Hemen şunuda belirteyimki bu tasarım deseni sizi uzaya götürmeyecektir, bu yüzden beklentilerinizi biraz daha azaltmanızda fayda var.
O halde "design pattern" yada "tasarım deseni" ni şu şekilde tanımlayabiliriz : Bir tasarım problemini en basit ve en efektif bir şekilde çözüme kavuşturacak yöntemdir.
Bildiğiniz üzere günümüzde yazılım mühendisliği alanında en fazla ses getiren kurgu yazılımın gerçek dünya ile olan ilişkisinin sağlanabilmesidir. Bu ilişki elbette nesne yönelimli programlama tekniği ile sağlanmaktadır. Nesne yönelimli programlama tekniği bilgisayar uygulamalarını soyut bir olgudan çıkararak insanların daha kolay algılayabileceği hale getirmiştir. Öyle görünüyorki, makro düzeyde gerçek hayatı modelleme ile başlayan bu ilişki mikro düzeydede büyük ses getirecektir. Nitekim son yıllarda geliştirilen yapay sinir ağları ile makinelerin çalışma sistemlerinin gün geçtikçe insanların veya canlıların çalışma şekline yaklaştığı görülmektedir. Artık bilgisayarlardan sadece verilen komutları yerine getirmek değil, belirli olaylar ve durumlar karşısında bazı hükümlere varabilmeleride istenmektedir. Burada vurgulamak istediğim nokta şudur : bizler yazılım mühendisleri veya programcılar olarak gerçek hayatı ne kadar iyi modelleyebiliyorsak o kadar başarılı sayılırız. Peki "desgin pattern" konusu nerede devreye girmektedir? İşte benimde gelmek istediğim nokta budur; "desgin patterns" bir modelin tasarımın ustaca tasarlanmasını sağlayacak çeşitli desenlerin oluşturulmasını ve bu desenlerin ihtiyaç dahilinde herhangi bir modelin inşaasında kullanılabilmesini sağlar. "Design pattern" kavramı bir kurallar topluluğundan ziyade bir işi nasıl ve en güzel ne şekilde yapabileceğimiz gösteren yöntemler topluluğudur. Öyleki iyi bir yazılım modelleyicisiyseniz kendi tasarım desenlerinizi oluşturabilir ve bunları diğer ustaların kullanımına sunabilirsiniz. Tasarım desenleri tecrübe ile oluşturulan yapılardır. Bazıları olmazsa olmaz yapılar olmasına rağmen bazıları tamamen yazılımın sanatsal yönünü göstermek için tasarlanmıştır . Örneğin bu yazımın ana konusunu belirleyen "Singleton" tasarım deseni yıllardan beri bir çok kişi tarafından kullanılmıştır. Sizde bu yazıda bu desenin amacını ve nasıl uygulandığını öğrendiğinizde eminimki projelerinizde mutlaka kullanacaksınız. Hemen şunuda belirteyimki bu tasarım deseni sizi uzaya götürmeyecektir, bu yüzden beklentilerinizi biraz daha azaltmanızda fayda var.
O halde "design pattern" yada "tasarım deseni" ni şu şekilde tanımlayabiliriz : Bir tasarım problemini en basit ve en efektif bir şekilde çözüme kavuşturacak yöntemdir.
"Design Pattern" Kaynakları
"Design Pattern" konusunda yazılmış en güzel ve en popüler kaynaklardan biri Erich Gamma, Richard Helm, Ralph Johnson ve John Vlissides tarafından kaleme alınmış "Design Patterns: Elements of Reusable Object-Oriented Software" kitabıdır. Bu kitapta en popüler tasarım desenleri anlatılmış ve bu desenlerin çeşitli uygulamalarına yer verilmiştir. "Desgin pattern" guru'ları olarak anılan bu 4 kişi "Gangs Of Four(GOF)" olarak ta bilinmektedir. Zaten bahsi geçen kitapta anlatılan tasarım desenlerine de genel olarak GoF tasarım desenleri denilmektedir. Bu yazı ile başlayan yazı dizisinde GOF olarak anılan tasarım desenlerini sizlere aktarıp çeşitli kullanım alanlarını açıklayacağım.
GOF tasarım desenleri genel olarak 3 ana grup altında incelenir. Bu gruplar ve herbir gruptaki tasarım desenlerinin isimleri aşağıda verilmiştir.
1 - Creatinal Patterns Bu desenler bir yada daha fazla nesnenin oluşturulması ve yönetilmesi ile ilgilidir. Örneğin bu yazıda anlatacağım ve bir uygulamanın ömrü boyunca belirli bir nesneden sadece bir adet bulunmasını garantileyen Singleton deseni bu gruba girmektedir. Bu gruptaki diğer desenler ise
"Design Pattern" konusunda yazılmış en güzel ve en popüler kaynaklardan biri Erich Gamma, Richard Helm, Ralph Johnson ve John Vlissides tarafından kaleme alınmış "Design Patterns: Elements of Reusable Object-Oriented Software" kitabıdır. Bu kitapta en popüler tasarım desenleri anlatılmış ve bu desenlerin çeşitli uygulamalarına yer verilmiştir. "Desgin pattern" guru'ları olarak anılan bu 4 kişi "Gangs Of Four(GOF)" olarak ta bilinmektedir. Zaten bahsi geçen kitapta anlatılan tasarım desenlerine de genel olarak GoF tasarım desenleri denilmektedir. Bu yazı ile başlayan yazı dizisinde GOF olarak anılan tasarım desenlerini sizlere aktarıp çeşitli kullanım alanlarını açıklayacağım.
GOF tasarım desenleri genel olarak 3 ana grup altında incelenir. Bu gruplar ve herbir gruptaki tasarım desenlerinin isimleri aşağıda verilmiştir.
1 - Creatinal Patterns Bu desenler bir yada daha fazla nesnenin oluşturulması ve yönetilmesi ile ilgilidir. Örneğin bu yazıda anlatacağım ve bir uygulamanın ömrü boyunca belirli bir nesneden sadece bir adet bulunmasını garantileyen Singleton deseni bu gruba girmektedir. Bu gruptaki diğer desenler ise
Abstract Factory Builder Factory Method Prototype
olarak bilinmektedir. Bu desenlerin bir çoğunu ilerleyen yazılarımda ele alacağım. Şimdilik sadece bir giriş yapıyoruz.
2 - Behavioral Patterns Bu gruptaki desenlerin amacı belirli bir işi yerine getirmek için çeşitli sınıfların nasıl birlikte davranabileceğinin belirlenmesidir. Bu gruptaki desenler ise aşağıdaki gibidir.
Chain of responsibility Command Interpreter Iterator Mediator Memento Observer State Strategy Template method Visitor
3 - Structural Patterns Bu gruptaki desenler ise çeşitli nesnelerin birbirleri ile olan ilişkileri temel alınarak tasarlanmıştır. Bu gruptaki tasarım desenleri ise şunlardır:
Adapter Bridge Composite Decorator Façade Flyweight Proxy
Bu giriş bilgisinden sonra şimdi nesnelerin yaratılması ile ilgili grup olan "Creatinal Patterns" grubunda bulunan "Singleton" desenini açıklamaya başalayabiliriz.
Singleton Deseni
Singleton deseni bir programın yaşam süresince belirli bir nesneden sadece bir örneğinin(instance) olmasını garantiler. Aynı zamanda bu desen, yaratılan tek nesneye ilgili sınıfın dışından global düzeyde mutlaka erişilmesini hedefler. Örneğin bir veritabanı uyglaması geliştirdiğinizi düşünelim. Her programcı mutlaka belli bir anda sadece bir bağlantı nesnesinin olmasını isteyecektir. Böylece her geretiğinde yeni bir bağlantı nesnesi yaratmaktansa varolan bağlantı nesnesi kullanılarak sistem kaynaklarının daha efektif bir şekilde harcanması sağlanır. Bu örnekleri dahada artırmak mümkündür. Siz ne zaman belli bir anda ilgili sınıfın bir örneğine ihtiyaç duyarsanız bu deseni kullanabilirsiniz.
Peki bu işlemi nasıl yapacağız.? Nasıl olacakta bir sınıftan sadece ve sadece bir nesne yaratılması garanti altına alınacak? Aslında biraz düşünürseniz cevabını hemen bulabilirsiniz! Çözüm gerçekten de basit : statik üye elemanlarını kullanarak.
Singleton tasarım desenine geçmeden önce sınıflar ve nesneler ile ilgili temel bilgilerimizi hatırlayalım. Hatırlayacağınız üzere bir sınıftan yeni bir nesne oluşturmak için yapıcı metot(constructor) kullanılır. Yapıcı metotlar C# dilinde new anahtar sözcüğü kullanılarak aşağıdaki gibi çağrılabilmektedir.
Sınıf nesne = new Sınıf();
Bu şekilde yeni bir nesne oluşturmak için new anahtar sözcüğünün temsil ettiği yapıcı metoduna dışarıdan erişimin olması gerekir. Yani yapıcı metodun public olarak bildirilmiş olması gerekir. Ancak "Singleton" desenine göre belirli bir anda sadece bir nesne olabileceği için new anahtar sözcüğünün ilgili sınıf için yasaklanması gerekir yani yapıcı metodun protected yada private olarak bildirilmesi gerekir. Eğer bir metodun varsayılan yapıcı metodu(default constructor- parametresiz yapıcı metot) public olarak bildirilmemişse ilgili sınıf türünden herhangi bir nesnenin sınıfın dışında tanımlanması mümkün değildir. Ancak bizim isteğimiz yalnızca bir nesnenin yaratılması olduğuna göre ilgili sınıfın içinde bir yerde nesnenin oluşturulması gerekir. Bunu elbette statik bir özellik(property) yada statik bir metotla yapacağız. Bu statik metot sınıfın kendi içinde yaratılan nesneyi geri dönüş değeri olarak bize gönderecektir. Peki bu nesne nerde ve ne zaman yaratılacaktır? Bu nesne statik metodun yada özelliğin içinde yaratılıp yine sınıfın private olan elemanına atanır. Tekil olarak yaratılan bu nesne her istendiğinde eğer nesne zaten yaratılmışsa bu private olan elemanın referasına geri dönmek yada nesneyi yaratıp bu private değişkene atamak gerekmektedir. Sanırım bu deseni nasıl uygulayabileceğimizi kafanızda biraz canlandırdınız. O halde daha fazla uzatmadan desenimizi uygulamaya geçirelim.
olarak bilinmektedir. Bu desenlerin bir çoğunu ilerleyen yazılarımda ele alacağım. Şimdilik sadece bir giriş yapıyoruz.
2 - Behavioral Patterns Bu gruptaki desenlerin amacı belirli bir işi yerine getirmek için çeşitli sınıfların nasıl birlikte davranabileceğinin belirlenmesidir. Bu gruptaki desenler ise aşağıdaki gibidir.
Chain of responsibility Command Interpreter Iterator Mediator Memento Observer State Strategy Template method Visitor
3 - Structural Patterns Bu gruptaki desenler ise çeşitli nesnelerin birbirleri ile olan ilişkileri temel alınarak tasarlanmıştır. Bu gruptaki tasarım desenleri ise şunlardır:
Adapter Bridge Composite Decorator Façade Flyweight Proxy
Bu giriş bilgisinden sonra şimdi nesnelerin yaratılması ile ilgili grup olan "Creatinal Patterns" grubunda bulunan "Singleton" desenini açıklamaya başalayabiliriz.
Singleton Deseni
Singleton deseni bir programın yaşam süresince belirli bir nesneden sadece bir örneğinin(instance) olmasını garantiler. Aynı zamanda bu desen, yaratılan tek nesneye ilgili sınıfın dışından global düzeyde mutlaka erişilmesini hedefler. Örneğin bir veritabanı uyglaması geliştirdiğinizi düşünelim. Her programcı mutlaka belli bir anda sadece bir bağlantı nesnesinin olmasını isteyecektir. Böylece her geretiğinde yeni bir bağlantı nesnesi yaratmaktansa varolan bağlantı nesnesi kullanılarak sistem kaynaklarının daha efektif bir şekilde harcanması sağlanır. Bu örnekleri dahada artırmak mümkündür. Siz ne zaman belli bir anda ilgili sınıfın bir örneğine ihtiyaç duyarsanız bu deseni kullanabilirsiniz.
Peki bu işlemi nasıl yapacağız.? Nasıl olacakta bir sınıftan sadece ve sadece bir nesne yaratılması garanti altına alınacak? Aslında biraz düşünürseniz cevabını hemen bulabilirsiniz! Çözüm gerçekten de basit : statik üye elemanlarını kullanarak.
Singleton tasarım desenine geçmeden önce sınıflar ve nesneler ile ilgili temel bilgilerimizi hatırlayalım. Hatırlayacağınız üzere bir sınıftan yeni bir nesne oluşturmak için yapıcı metot(constructor) kullanılır. Yapıcı metotlar C# dilinde new anahtar sözcüğü kullanılarak aşağıdaki gibi çağrılabilmektedir.
Sınıf nesne = new Sınıf();
Bu şekilde yeni bir nesne oluşturmak için new anahtar sözcüğünün temsil ettiği yapıcı metoduna dışarıdan erişimin olması gerekir. Yani yapıcı metodun public olarak bildirilmiş olması gerekir. Ancak "Singleton" desenine göre belirli bir anda sadece bir nesne olabileceği için new anahtar sözcüğünün ilgili sınıf için yasaklanması gerekir yani yapıcı metodun protected yada private olarak bildirilmesi gerekir. Eğer bir metodun varsayılan yapıcı metodu(default constructor- parametresiz yapıcı metot) public olarak bildirilmemişse ilgili sınıf türünden herhangi bir nesnenin sınıfın dışında tanımlanması mümkün değildir. Ancak bizim isteğimiz yalnızca bir nesnenin yaratılması olduğuna göre ilgili sınıfın içinde bir yerde nesnenin oluşturulması gerekir. Bunu elbette statik bir özellik(property) yada statik bir metotla yapacağız. Bu statik metot sınıfın kendi içinde yaratılan nesneyi geri dönüş değeri olarak bize gönderecektir. Peki bu nesne nerde ve ne zaman yaratılacaktır? Bu nesne statik metodun yada özelliğin içinde yaratılıp yine sınıfın private olan elemanına atanır. Tekil olarak yaratılan bu nesne her istendiğinde eğer nesne zaten yaratılmışsa bu private olan elemanın referasına geri dönmek yada nesneyi yaratıp bu private değişkene atamak gerekmektedir. Sanırım bu deseni nasıl uygulayabileceğimizi kafanızda biraz canlandırdınız. O halde daha fazla uzatmadan desenimizi uygulamaya geçirelim.
Singleton
Deseninin 1. versiyonu
public class SingletonDeseni
{
private static SingletonDeseni nesne = new SingletonDeseni();
private SingletonDeseni()
{
}
public static SingletonDeseni Nesne
{
get
{
return nesne;
}
}
}
{
private static SingletonDeseni nesne = new SingletonDeseni();
private SingletonDeseni()
{
}
public static SingletonDeseni Nesne
{
get
{
return nesne;
}
}
}
Yukarıdaki sınıf örneğinde SingletonDeseni sınıfı belleğe yüklendiği
anda statik olan SingletonDeseni nesnesi yaratılacaktır. Bu nesne yaratılışının
new anahtar sözcüğü ile yapıldığına dikkat edin. Eğer siz Main() gibi bir
metodun içinden bu nesneyi yaratmaya kalksaydınız derleme aşamasında hata alırdınız.
Çünkü public olan herhangi bir yapıcı metot bulunmamaktadır. Ayrıca
Siz Main() gibi bir metodun içinden yaratılan bu nesneye
SingletonDeseni nesne = SingletonDeseni.Nesne;
şeklinde erişmeniz mümkündür. Böylece yukarıdaki deyimi her kullandığınızda size geri dönen nesne, sınfıın belleğe ilk yüklendiğinde yaratılan nesne olduğu garanti altına alınmış oldu. Dikkat etminiz gereken diğer bir nokta ise nesneyi geri döndüren özelliğin yalnızca get bloğunun olmasıdır. Böylece bir kez yaratılan nesne harici bir kaynak tarafından hiç bir şekilde değiştirilemeyecektir.
Yukarıdaki SingletonDeseni sınıfını aşağıdaki gibi de yazmamız mümkündür.
Singleton Deseninin 2. versiyonu
Siz Main() gibi bir metodun içinden yaratılan bu nesneye
SingletonDeseni nesne = SingletonDeseni.Nesne;
şeklinde erişmeniz mümkündür. Böylece yukarıdaki deyimi her kullandığınızda size geri dönen nesne, sınfıın belleğe ilk yüklendiğinde yaratılan nesne olduğu garanti altına alınmış oldu. Dikkat etminiz gereken diğer bir nokta ise nesneyi geri döndüren özelliğin yalnızca get bloğunun olmasıdır. Böylece bir kez yaratılan nesne harici bir kaynak tarafından hiç bir şekilde değiştirilemeyecektir.
Yukarıdaki SingletonDeseni sınıfını aşağıdaki gibi de yazmamız mümkündür.
Singleton Deseninin 2. versiyonu
Dikkat ederseniz iki sınıfın tek farkı oluşturulan nesneye erişme
biçimidir. İlk versiyonda nesneye özellik üzerinden erişilirken ikinci
versiyonda metot üzerinden erişilmektedir. Değişmeyen tek nokta ise her iki erişim
aracının da statik olmasıdır.
Yukarıdaki her iki versiyonda da biz yaratılan nesneyi
SingletonDeseni nesne = SingletonDeseni.Nesne;
yada
SingletonDeseni nesne = SingletonDeseni.Nesne();
şeklinde istediğimizde nesne zaten yaratılmış durumda olmaktadır. Oysa bu sınıfı daha efektif bir hale getirerek yaratılacak nesnenin ancak biz onu istediğimizde yaratılmasını sağlayabiliriz. Bu durumu uygulayan Singleton deseninin 3 versiyonunu olarak aşağıda görebilirsiniz.
Singleton Deseninin 3. versiyonu
Yukarıdaki her iki versiyonda da biz yaratılan nesneyi
SingletonDeseni nesne = SingletonDeseni.Nesne;
yada
SingletonDeseni nesne = SingletonDeseni.Nesne();
şeklinde istediğimizde nesne zaten yaratılmış durumda olmaktadır. Oysa bu sınıfı daha efektif bir hale getirerek yaratılacak nesnenin ancak biz onu istediğimizde yaratılmasını sağlayabiliriz. Bu durumu uygulayan Singleton deseninin 3 versiyonunu olarak aşağıda görebilirsiniz.
Singleton Deseninin 3. versiyonu
public class SingletonDeseni
{
private static SingletonDeseni nesne;
private SingletonDeseni()
{
}
public static Singleton Nesne()
{
if(nesne == null)
nesne = new SingletonDeseni();
return nesne;
}
}
{
private static SingletonDeseni nesne;
private SingletonDeseni()
{
}
public static Singleton Nesne()
{
if(nesne == null)
nesne = new SingletonDeseni();
return nesne;
}
}
Gördüğünüz üzere nesne ilk olarak sınıf belleğe yüklendiğinde değilde o
nesneyi ilk defa kullanmak istediğimizde yaratılıyor. İlgili nesneyi her istediğimizde
yeni bir nesnenin yaratılmaması içinde
if(nesne == null)
şeklinde bir koşul altında nesnenin yaratıldığına dikkat edin.
Not : 3.versiyonda nesneyi yaratan bir metot olabileceği gibi 1. versiyondaki gibi sadece get bloğu olan özellikte olabilir.
Herşeye rağmen yukarıdaki 3 versiyonda bazı durumlar için tek bir nesnenin oluşmasını garanti etmemiş olabilirz. Eğer çok kanallı(multi-thread) bir uygulama geliştiriyoırsanız farklı kanalların aynı nesneyi tekrar yaratması olasıdır. Ancak eğer çok kanallı çalışmıyorsanız(çoğunlukla tek thread ile çalışırız) yukarıdaki sade ama öz olan 3 versiyondan birini kullanabilirsiniz. Ama eğer çok kanallı programlama modeli söz konusu ise ne yazıkki farklı kanalların aynı nesneden tekrar yaratmasını engelemek için ekstra kontroller yapmanız gerekmektedir. Ne yazıkki diyorum çünkü bu yapacağımız kontrol performansı büyük ölçüde düşürmektedir.
O halde çok kanallı uygulamalarda kullanabileceğimiz Singleton desenini yazalım.
Singleton Deseninin 4. versiyonu
if(nesne == null)
şeklinde bir koşul altında nesnenin yaratıldığına dikkat edin.
Not : 3.versiyonda nesneyi yaratan bir metot olabileceği gibi 1. versiyondaki gibi sadece get bloğu olan özellikte olabilir.
Herşeye rağmen yukarıdaki 3 versiyonda bazı durumlar için tek bir nesnenin oluşmasını garanti etmemiş olabilirz. Eğer çok kanallı(multi-thread) bir uygulama geliştiriyoırsanız farklı kanalların aynı nesneyi tekrar yaratması olasıdır. Ancak eğer çok kanallı çalışmıyorsanız(çoğunlukla tek thread ile çalışırız) yukarıdaki sade ama öz olan 3 versiyondan birini kullanabilirsiniz. Ama eğer çok kanallı programlama modeli söz konusu ise ne yazıkki farklı kanalların aynı nesneden tekrar yaratmasını engelemek için ekstra kontroller yapmanız gerekmektedir. Ne yazıkki diyorum çünkü bu yapacağımız kontrol performansı büyük ölçüde düşürmektedir.
O halde çok kanallı uygulamalarda kullanabileceğimiz Singleton desenini yazalım.
Singleton Deseninin 4. versiyonu
public class SingletonDeseni
{
private static SingletonDeseni nesne;
private static Object kanalKontrol = new Object;
private SingletonDeseni()
{
}
public static Singleton Nesne()
{
if(nesne == null)
{
lock(kanalKontrol)
{
if(nesne == null)
{
nesne = new SingletonDeseni();
}
}
}
return nesne;
}
}
{
private static SingletonDeseni nesne;
private static Object kanalKontrol = new Object;
private SingletonDeseni()
{
}
public static Singleton Nesne()
{
if(nesne == null)
{
lock(kanalKontrol)
{
if(nesne == null)
{
nesne = new SingletonDeseni();
}
}
}
return nesne;
}
}
Yukarıdaki desendeki püf nokta lock anahtar sözcüğünün kullanımıdır.Eğer
nesne ilk defa yaratılcaksa yani daha önceden nesne null değere sahipse lock
anahtar sözcüğü ile işaretlenen blok kitlenerek başka kanalların bu bloğa erişmesi
engellenir. Böylece kilitleme işlemi bittiğinde nesne yaratılmış olacağı için,
kilidin kalkmasını bekleyen diğer kanal lock bloğuna girmiş olsa bile bu
bloktaki ikinci if kontrolü nesnenin yeniden oluşturulmasını engelleyecektir.
Böylece çok kanallı uygulamalar içinde tek bir nesnenin oluşmasını ve bu
nesneye erişimi garanti altına alan Singleton desenini tasarlamış olduk.
Son olarak lock anahtar sözcüğünü kullanmadan çok kanallı uygulamalar içinde tek bir nesneyi garanti altına alacak deseni yazalım. Aşağıda Singleton desenin 5. versiyonu bulunmaktadır.
Singleton Deseninin 5. versiyonu
Son olarak lock anahtar sözcüğünü kullanmadan çok kanallı uygulamalar içinde tek bir nesneyi garanti altına alacak deseni yazalım. Aşağıda Singleton desenin 5. versiyonu bulunmaktadır.
Singleton Deseninin 5. versiyonu
public class SingletonDeseni
{
private static SingletonDeseni nesne = new SingletonDeseni ();
private static SingletonDeseni()
{
}
private SingletonDeseni()
{
}
public static SingletonDeseni Nesne
{
get
{
return nesne;
}
}
}
{
private static SingletonDeseni nesne = new SingletonDeseni ();
private static SingletonDeseni()
{
}
private SingletonDeseni()
{
}
public static SingletonDeseni Nesne
{
get
{
return nesne;
}
}
}
Bu versiyonun birinci versiyondan tek farkı yapıcı metodunda statik
olmasıdır. C# dilinde statik yapıcı metotlar bir uygulama domeninde ancak ve
ancak bir nesne yaratıldığında yada statik bir üye eleman referans edildiğinde
bir defaya mahsus olmak üzere çalıştırılır. Yani yukarıdaki versiyonda farklı
kanalların(thread) birden fazla SingletonDeseni nesnesi yaratması imkansızdır.
Çünkü static üye elemanlar ancak ve ancak bir defa çalıştırılır.
Son versyion basit ve kullanışlı görünmesine rağmen kullanımının bazı sakıncaları vardır. Örneğin Nesne Özelliği dışında herhangi bir statik üye elemanınız var ise ve ilk olarak bu statik üye elemanını kullanıyorsanız siz istemedğiniz halde SingletonDeseni nesnesi yaratılacaktır. Zira yukarıda da dediğimz gibi bir statik yapıcı metot herhangi bir statik üye elemanı kullanıldığı anda çalıştırılır. Diğer bir sakıncalı durumda birbirini çağıran statik yapıcı metotların çağrılması sırasında çelişkilerin oluşabileceğidir. Örneğin her static yapıcı metot ancak ve ancak bir defa çalıştırılır dedik. Eğer çalıştırılan bir static metot diğer bir statik metodu çağırıyor ve bu statik metotta ilkini çağırıyorsa bir çelişki olacaktır.
Kısacası eğer kodunuzun çelişki yaratmayacağından eminseniz 5. deseni kullanmanız doğru olacaktır. Eğer çok kanallı uygulama geliştiriyorsanız 4. versiyonu, çok kanallı uygulama geliştirmiyorsanızda 3. versiyonu kullanmanız tavsiye edilmektedir.
Son versyion basit ve kullanışlı görünmesine rağmen kullanımının bazı sakıncaları vardır. Örneğin Nesne Özelliği dışında herhangi bir statik üye elemanınız var ise ve ilk olarak bu statik üye elemanını kullanıyorsanız siz istemedğiniz halde SingletonDeseni nesnesi yaratılacaktır. Zira yukarıda da dediğimz gibi bir statik yapıcı metot herhangi bir statik üye elemanı kullanıldığı anda çalıştırılır. Diğer bir sakıncalı durumda birbirini çağıran statik yapıcı metotların çağrılması sırasında çelişkilerin oluşabileceğidir. Örneğin her static yapıcı metot ancak ve ancak bir defa çalıştırılır dedik. Eğer çalıştırılan bir static metot diğer bir statik metodu çağırıyor ve bu statik metotta ilkini çağırıyorsa bir çelişki olacaktır.
Kısacası eğer kodunuzun çelişki yaratmayacağından eminseniz 5. deseni kullanmanız doğru olacaktır. Eğer çok kanallı uygulama geliştiriyorsanız 4. versiyonu, çok kanallı uygulama geliştirmiyorsanızda 3. versiyonu kullanmanız tavsiye edilmektedir.
Hiç yorum yok:
Yorum Gönder