Merhaba arkadaşlar. Bu yazımda sıkça kullanılan programcılık desenlerinden Singleton üzerinde durmaya çalışacağız.
Gang of Four kitabı olarak bilinen ve konu ile ilgili detaylı bilgiyi bizlere sunan bir çok kitap mevcuttur. Ben size aşağıdaki kitabı şiddetle tavsiye etmekteyim.;
Elements of Reusable Object Oriented Software by Erich Gamma, Richard Helm, Ralph Johnson and John Vlissides.
Eğer programcılık ile ilgileniyorsanız bu kitap yazılım mimari tasarımı vizyonunuza önemli faydalar sağlayacaktır.
Lafı fazla uzatmadan konuya giriş yapacağım.
Singleton nedir, ne demektir?
Eğer geliştirdiğiniz yazılımın genelinde aynı nesneye sıkça ihtiyaç duyuyorsanız ve tek instance ile çalışmak istiyorsanız Singleton uygulamalısınız.
Singleton size her ne zaman nesneyi çağırırsanız çağırın hep aynı instance geri dönecektir. Singleton sıkça kullandığım konulardan birine örnek vermem gerekirse; Örneğin EventLoglama olayı için singleton kullanmaktayım. Dolayısı ile her loglama işleminde yeni bir nesne oluşturup hafızadan gereksiz yere yer işgal etmemekteyim. Örnekleri genişletebiliriz.
İsterseniz basit bir Singleton sınıfı neye benzemektedir bir görelim.
public class Singleton
{
private static Singleton _instance = null;
private Singleton()
{ }
public static Singleton Instance()
{
if (_instance == null)
{
_instance = new Singleton();
}
return _instance;
}
}
Yukarıda gördüğünüz üzere sınıfın constructor metodu private tanımlanmış durumda. Dolayısı ile sınıfdan instance yaratma özelliğini ortadan kaldırmış bulunmaktayım. Eğer illa bu sınıfdan bir instance return etmek isterseniz Instance() metodunu çağırmanız gerekmektedir. Bu metodda bize her zaman aynı instance ‘ı geri döndürecektir J
Multithread Singleton nedir, ne demektir?
Şu ana kadar herşey çok güzel ve hiç bir sıkıntı yok . Ama yukarıdaki kod size sadece singlethread uygulamalar geliştireceğiniz zaman fayda sağlayacatır. Eğer multithread (threadsafe) bir uygulama geliştirmek isterseniz bu sınıfda biraz değişiklik yapmanız gerekiyor.
public class MultiSingleton
{
private static volatile MultiSingleton _instance = null;
private MultiSingleton()
{ }
public static MultiSingleton Instance()
{
if (_instance == null)
{
lock (typeof(MultiSingleton))
{
if (_instance == null)
{
_instance = new MultiSingleton();
}
}
}
return _instance;
}
}
Görüldüğü üzere sadece değişken isminde ve Instance() metodunda ufak değişiklikler işinizi çözecektir. Instance yaratmadan önce aynı anda birden fazla istemci çağrısı karşısında sorun oluşmasını engellemek amacı ile lock yapmamız gerekiyor. Dikkat ederseniz değişken adının öncesine volatile keyword eklenmiştir. Bu sayede compilerınızın kafasına göre hafıza optimizasyonu yapmasını engellemiş bulunmaktayız. Bu demek şimdi diye sorabilirsiniz kendi kendinize. Anlatırız J Şimdi dikkat ederseniz çift if kontrolü var. Eğer compiler kafasına göre optimizasyon yaparsa bunlardan birisini kaldıracaktır. İşte biz buna engel olmuş bulunmaktayız. Peki Niye mi çift if kontrol koyduk kodun içerisine. Çünkü birden fazla thread aynı anda kodun aynı yerinde olabilir ve her iki thread de null sonucu ile geri dönebilir. Bu da istemediğimiz bir durumdur. Üstte bulunan if kaldırılırsada sorunsuz çalışacaktır. Fakat efficient bir kod olmayacaktır.
Örnekleri çalıştırmak için bir Windows Forms uygulaması oluşturup gerçekten aynı nesnenin döndüğünü görebilirsiniz.
Singleton S1;
Singleton S2;
S1 = Singleton.Instance();
S2 = Singleton.Instance();
MessageBox.Show(S1.Equals(S2).ToString());
Umarım buraya kadar herşey anlaşılmıştır. Eğer anlaşılamayan bir konu olursa tekrar açıklayabilirim. Bir sonraki makalemde Generic Singleton konusuna derinlemesine ineceğiz :)
Kendinize iyi bakın...