Singleton Pattern Nedir?
Singleton Pattern, bir sınıfın yalnızca bir kez oluşturulmasını sağlayarak birden fazla örnek oluşturulmasını engellemek ve ilgili sınıfa global bir erişim noktası sunmak amacıyla yaygın olarak kullanılan bir tasarım desenidir.

Erdoğancan Yüksel
3 dakika 8 saniye okuma süresi

Singleton Pattern Nedir?

Erdoğancan Yüksel
3 dakika 8 saniye okuma süresi
Singleton Pattern, bir sınıfın yalnızca bir kez oluşturulmasını sağlayarak birden fazla örnek oluşturulmasını engellemek ve ilgili sınıfa global bir erişim noktası sunmak amacıyla yaygın olarak kullanılan bir tasarım desenidir.

Singleton pattern, bir sınıfın yalnızca bir örneğinin(instance) oluşturulmasını sağlayarak bu örnek sınıfa global bir erişim noktası sunan bir tasarım desenidir. Sınıfın tüm uygulama boyunca yalnızca bir kez örneklenmesinin gerektiği durumlarda singleton pattern kullanmak oldukça fayda sağlamaktadır.
Bir sınıfın Singleton tasarım kalıbına uygun olması için temel olarak üç adım bulunmaktadır:
- Private constructor: Sınıfın dışarıdan örneklenmesinin önüne geçmek için constructor(yapıcı) metot private yapılmalıdır. Bu işlem class'tan new ile nesne oluşturulmasını engellemektedir.
- Statik Değişken: Singleton örneğinin tutulacağı statik bir değişken oluşturulmalıdır.
- Erişim Metodu: Singleton örneğine erişim sağlayacak statik bir metot oluşturulmalıdır.
Singleton design pattern, creational design pattern kategorisindedir ve kullanım senaryolarına aşağıdaki örnekler verilebilir:
- Konfigurasyon Yönetimi: Uygulama ayrlarının yönetimi için yalnızca bir örnek oluşturmak yeterli olduğundan singleton pattern tercih edilebilmektedir.
- Veritabanı Bağlantısı: Uygulamada kullanılacak olan veritabanı bağlantısı için tek bir örnek oluşturmak yeterli olduğundan singleton pattern tercih edilebilmektedir.
- Cache Yönetimi: Önbelleğe alınan veriler uygulamanın birden fazla yerinde kullanılabileceğinden singleton pattern tercih edilebilmektedir.
- Loglama Sistemi: Uygulama genelinde kullanılacak log sistemi için singleton pattern tercih edilebilmektedir.
C# ile Singleton Pattern Uygulaması
C#'ta singleton tasarım kalıbını uygulamanın çeşitli yolları bulunmaktadır. Bunlar arasında en yaygın olarak kullanılanlar Basit Singleton (Thread-Safe Olmayan), Thread-Safe Singleton ve Lazy Initialization (Tembel Yükleme)'dır.
1.Basit Singleton (Thread-Safe Olmayan)
Thread-safe olmayan basit bir singleton uygulaması için kod örneği:
public sealed class Singleton
{
// Singleton instance'ı tutan statik değişken
private static Singleton _instance;
// Yapıcı(Constructor) metodun private olması dışarıdan instance oluşturulmasını engeller.
private Singleton() { }
// Singleton'a erişim sağlayan public statik metot
public static Singleton Instance
{
get
{
// Instance yok ise yeni instance oluşturulur.
if (_instance is null) _instance = new Singleton();
return _instance;
}
}
}
// Kullanımı için:
Singleton singleton = Singleton.Instance;
if (singleton != null) Console.WriteLine("Singleton works!");
//# Output:
Singleton works!
2.Thread-Safe Singleton
Çoklu iş parçacığı(Multi-threaded) uygulamalarda Singleton Pattern'ın düzgün çalışmasını sağlamak için iş parçacığı güvenliği(thread-safe) uygulanması gerekmektedir. Aksi durumda Instance metoduna birden fazla iş parçacığı aynı anda erişir ise birden fazla örnek oluşturulabilmektedir. Lock mekanizması bunu sağlamaktadır.
Thread-safe singleton uygulaması için kod örneği:
public sealed class Singleton
{
private static Singleton _instance;
private static readonly object _lock = new object();
private Singleton() { }
public string? Value { get; set; }
public static Singleton GetInstance(string value)
{
//Buradaki if değeri kilitleme işleminin her işlemde devreye girmesini engellemek için eklenmiştir.
//Bu sayede instance null olmadığı durumlarda kilitleme işlemi devreye girmez.
if (_instance is null)
{
// Thread-safe mekanizması
lock (_lock)
{
if (_instance is null)
{
_instance = new Singleton();
_instance.Value = value;
}
}
}
return _instance;
}
}
// Kullanımı için:
Thread process1 = new Thread(() =>
{
TestThreadSafeSingleton("Test-1");
});
Thread process2 = new Thread(() =>
{
TestThreadSafeSingleton("Test-2");
});
process1.Start();
process2.Start();
process1.Join();
process2.Join();
static void TestThreadSafeSingleton(string value)
{
Singleton singleton = Singleton.GetInstance(value);
Console.WriteLine(singleton.Value);
}
// Sonuçlarda aynı değerin çıktı olarak alınması singleton'ın tekrar kullanıldığı anlamına gelmektedir.
// Lock mekanizmasının çalıştığını göstermektedir.
//# Output:
Test-1
Test-1
3.Lazy Initialization (Tembel Yükleme)
Singleton nesnesinin gerektiği durumlarda yüklenmesini sağlamak için lazy initialization kullanılabilmektedir. Lazy<T> sınıfı kullanılarak lazy loading (tembel yükleme) işlemi kolayca uygulanabilmektedir.
Lazy Initialization uygulaması için kod örneği:
public sealed class Singleton
{
private static readonly Lazy<Singleton> lazy =
new Lazy<Singleton>(() => new Singleton());
public static Singleton Instance { get { return lazy.Value; } }
private Singleton()
{
}
}
C# ile Singleton Pattern Uygulaması Örnekleri
Gerçek dünya senaryoları için singleton tasarım kalıbının nasıl kullanılabileceğini detaylı bir örnek ile birlikte inceleyelim.Logger Sınıfı için singleton tasarım kalıbı uygulamasının kod örneği:
namespace SingletonPattern;
public sealed class Logger
{
private static readonly Lazy<Logger> _logger = new Lazy<Logger>(() => new Logger());
private string _filePath;
private Logger()
{
_filePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "application_logs.txt");
}
public static Logger Instance => _logger.Value;
public void Log(string message)
{
string logMessage = $"{DateTime.Now:yyyy-MM-dd HH:mm:ss} - {message}";
try
{
using(StreamWriter writer = File.AppendText(_filePath))
{
writer.WriteLine(logMessage);
}
Console.WriteLine($"Logged: {logMessage}");
}
catch (Exception ex)
{
Console.WriteLine($"Error writing to log file: {ex.Message}");
}
}
public string GetLogFilePath() => _filePath;
}
// Logger Sınıfının Kullanımı
Logger.Instance.Log("Application started!");
Logger.Instance.Log("Process finished!");
Logger.Instance.Log("Application closed!");
Console.WriteLine($"Log dosyası: {Logger.Instance.GetLogFilePath()}");
Yukarıdaki örnekte singleton tasarım deseninin uygulanması sayesinde Logger sınıfı üzerinden yazılacak her log datası aynı log dosyası üzerine yazılacaktır.
Sonuç olarak Singleton Pattern yazılım dünyasında tercih edilen kullanışlı bir tasarım desenidir. Ancak singleton tasarım kalıbı ile uygulanan her yeni global durum bağımlılığı arttırabildiğinden dolayı bu durum uygulamada esnekliği olumsuz olarak etkileyebilmektedir. Bu nedenle singleton tasarım kalıbının gerçekten gerekli olduğu durumlarda kullanılması gerekmektedir.
Benzer İçerikler

Adapter Pattern Nedir?
Adapter Pattern, uyumsuz arayüzlere sahip iki sınıfın birlikte çalışmasını sağlamak amacıyla kullanılan yapısal (structural) tasarım desenlerinden birisidir. Bir sınıfın arayüzünü (interface) başka bir sınıfın beklediği arayüze dönüştürerek iki sınıf arasında bir köprü kurmaktadır.
5 Ekim 2024
2 dakika 46 saniye okuma süresi

Factory Method Pattern Nedir?
Factory Pattern, nesne oluşturma sürecinin soyutlayıp bir merkezde toplayarak hangi sınıfın örneğinin oluşturulması gerektiğine karar veren bir sınıf tanımlanması için kullanılan yaratıcı (creational) tasarım desenlerinen birisidir. Özellikle karmaşık nesne yaratma işlemlerinin kontrol edilmesi gereken durumlarda kodun daha esnek ve sürdürülebilir olmasını sağlamaktadır.
11 Ekim 2024
2 dakika 10 saniye okuma süresi

Builder Pattern Nedir?
Builder Pattern, yazılım geliştirme süreçlerinde karmaşık nesnelerin oluşturulması sürecini basitleştirerek bir nesnenin oluşturulmasını ve yapılandırılmasını adım adım yönetmeyi sağlayan ve kodun okunabilirliğini kolaylaştıran tasarım desenidir.
7 Kasım 2024
2 dakika 42 saniye okuma süresi

Prototype Pattern Nedir?
Prototype Pattern, mevcuttaki bir nesne örneğinin kopyalanarak benzer özelliklere sahip yeni nesneler oluşturulması için kullanılan bir tasarım desenidir.
13 Kasım 2024
2 dakika 29 saniye okuma süresi