C#'ta Singleton Tasarım Deseninin Kullanımı

C#'ta singleton tasarım deseninin açıklanması ve kullanılmasını ele alalım.

Singleton Design Pattern, Creatinal Patterns gurubu içerisinde yer alır. Uygulamanın çalışma süresi boyunca bir nesnenin sadece tek bir örneğinin oluşturulmasının garanti altına alınması istenildiğini durumlarda singleton pattern kullanılır.

Konuyu bir donanım aygıtı ile örneklendirelim. Bir DVD-RW cihazımız olsun. Bu cihaz dvd yazma ve okumayı aynı anda gerçekleştiremez. DVD nesnesinin birden fazla örneğini oluşturmak ve kullanmak karmaşaya yol açacaktır. Bir nesneden yazma komutunu çalıştırmak diğer nesneden okuma işlemi yapmaya çalışmak hatalara neden olacaktır. Burada ortaya çıkan ihtiyaç/problem için başvuru kaynağımız singleton pattern olacaktır.

Amacımız sistemimize bağlı olan bir DVD cihazını yalnızca bir nesne ile temsil etmek.

namespace ConsoleApplication1
{
public class DVDDevice
{
private static DVDDevice dvdDevice = new DVDDevice();
// 1.Yol DvdDevice nesnesine Property üzerinden ulaşmak
public static DVDDevice Device
{
get
{
return dvdDevice;
}
}
//2.Yol DvdDevice nesnesine Method üzerinden ulaşmak
public static DVDDevice GetDevice()
{
return dvdDevice;
}
}
class Program
{
static void Main(string[] args)
{
//1.Yol
DVDDevice device = DVDDevice.Device;
//2.Yol
DVDDevice device = DVDDevice.GetDevice();
Console.Read();
}
}
}

DVDDevice sınıfı belleğe yüklenmesi ile dvdDevice static nesnesi yaratılacak ve o nesneyi kullanmak isteyen yapılar, yukarıdaki yaratılan nesnenin private erişim belirleyicisi ile tanımlanıp dışarıya kapatılması nedeniyle, örneklerde olduğu gibi bir property yada metod üzerinden nesneye ulaşacaklardır. Main metodunda görüldüğü gibi new anahtar sözcüğü kullanılmamıştır. Çünkü nesne burada yaratılmamıştır.

Nesnenin yaratılması DVDDevice sınıfının belleğe yüklendiği sırada değil bizim istediğimizherhangi bir zamanda olması istendiği durumda yukarıdaki yapıyı şu şekilde değiştireceğiz.

namespace ConsoleApplication1
{
public class DVDDevice
{
private static DVDDevice dvdDevice;
// 1.Yol DvdDevice nesnesine Property üzerinden ulaşmak
public static DVDDevice Device
{
get
{
if (dvdDevice == null)
dvdDevice = new DVDDevice();
return dvdDevice;
}
}
//2.Yol DvdDevice nesnesine Method üzerinden ula
public static DVDDevice GetDevice()
{
if (dvdDevice == null)
dvdDevice = new DVDDevice();
return dvdDevice;
}
}
class Program
{
static void Main(string[] args)
{
//1.Yol
DVDDevice device = DVDDevice.Device;
//2.Yol
DVDDevice device = DVDDevice.GetDevice();
Console.Read();
}
}
}

İlk örneğimizde:

private static DVDDevice dvdDevice = new DVDDevice();

dvdDevice nesnemiz new operatörü ile DVDDevice sınıfı belleğe yüklendiğinde otomatik olarak oluşturuluyordu. İkinci örneğimizde private static DVDDevice dvdDevice Nesnemiz tanımlandı fakat yaratılmadı.

Nesneye erişim için kullandığımız property ve metod içinde nesnenin durumu sorgulanıyor. Eğer nesne henüz yaratılmadı ise yeni bir nesne yaratıp bu nesneyi döndürüyor. Nesne daha önce yaratıldı ise yaratılan nesneyi döndürüyor.

if (dvdDevice == null)
dvdDevice = new DVDDevice();
return dvdDevice;

Multithread bir uygulamada birden fazla thread, singleton olarak tanımlamak istediğimiz nesneyi kullanma ihtiyacı duyarsa yapılacak şey işlem bitene kadar diğer thread'ler için bu bloğu kilitlemek. Kilit işlemi için global bir nesne yaratıyoruz.

private static readonly object LockObject = new object();

Ardından kod bloğmuzu bu şekilde değiştiriyoruz.

System.Threading.Monitor.Enter(LockObject);
if (dvdDevice == null)
dvdDevice = new DVDDevice();
return dvdDevice
System.Threading.Monitor.Exit(LockObject);

 

Yorum Yaz

Yorum yazabilmek için üye girişi yapmanız gerekiyor!

Yukarı Git