ESC را فشار دهید تا بسته شود

زمیوس آموزش، یادگیری و سرگرمی

Singleton در #C: آموزش الگوی طراحی Singleton با مثال

 الگوی Singleton در سی شارپ باعث می‌شود یک کلاس فقط یک نمونه (Instance) در کل برنامه داشته باشد و همه بخش‌ها به همان نمونه دسترسی داشته باشند.

ویژگی‌ها:

  1. ایجاد تنها یک شیء در کل چرخه حیات برنامه.
  2. دسترسی سراسری (Global) به آن نمونه.
  3. جلوگیری از ایجاد اشیاء جدید با new از خارج کلاس.
  4. کنترل همزمانی (Thread-Safety) برای برنامه‌های چند نخی.

مدیریت استثناها در سی‌شارپ (#C) یکی از مباحث کلیدی در آموزش برنامه نویسی سی شازپ  و توسعه نرم‌افزار است که به برنامه‌نویسان امکان می‌دهد خطاهای زمان اجرا را به‌طور مؤثر کنترل و مدیریت کنند.

پیشنهاد می شود نوشته زیر را مطالعه کنید:

در این نوشته شما می خوانید

Singleton در #C چیست و چه کاربردی دارد؟

الگوی طراحی Singleton یکی از معروف‌ترین GoF Design Patterns در دسته Creational Patterns است، که تضمین می‌کند فقط یک نمونه (Instance) از یک کلاس در طول اجرای برنامه ساخته شود و همه بخش‌ها به همان نمونه دسترسی داشته باشند.

اگر بخواهم ساده بگویم: Singleton مثل یک «مدیر کل» است که در کل سازمان فقط یک نفر از آن وجود دارد و همه باید کارشان را از طریق او جلو ببرند.

چرا از Singleton در #C استفاده کنیم؟

در پروژه‌های واقعی Singleton به درد این موارد می‌خورد:

  • سیستم لاگ (Logger): ثبت خطاها و رویدادها بدون ساخت نمونه‌های تکراری.
  • مدیریت تنظیمات (Configuration Manager): همه بخش‌های برنامه از یک جای واحد پیکربندی بگیرند.
  • اتصال به پایگاه داده: جلوگیری از ایجاد کانکشن‌های اضافی.
  • کش موقت (Cache): ذخیره نتایج پرمصرف با یک هسته مرکزی.
  • مدیریت Session در برنامه‌های وب.

ساختار اصلی الگوی Singleton در #C

تو نسخه ساده و رایج (Thread-Safe):

				
					public sealed class Singleton
{
    private static Singleton _instance = null;
    private static readonly object _lock = new object();

    // sazande khosoosi => jelo giri az NEW, nemoone jadid az biroon
    private Singleton()
    {
        Console.WriteLine("Singleton Instance Created");
    }

    // Property baraye access be nemoone ha.
    public static Singleton Instance
    {
        get
        {
            if (_instance == null) // check avalie
            {
                lock (_lock) // jelo giri az moshkel Multi-Thread
                {
                    if (_instance == null) // check dovom
                        _instance = new Singleton();
                }
            }
            return _instance;
        }
    }

    // method nemoone baraye test
    public void Log(string message)
    {
        Console.WriteLine($"[LOG] {message}");
    }
}

				
			

🧪 مثال عملی — Logger Singleton

فرض کن یک سایت پر بازدید داری که لاگ گرفتن از درخواست‌ها خیلی مهمه. اگر کلاس Logger هر بار نمونه جدید بسازه، منابع هدر می‌رود.

پس Singleton بهترین انتخاب است:

				
					public class Program
{
    public static void Main(string[] args)
    {
        // Hame inha Be yek Logger Asli Vaslan
        Singleton.Instance.Log("User logged in");
        Singleton.Instance.Log("Database query executed");
        Singleton.Instance.Log("Error: Out of memory");
    }
}

				
			

خروجی:

				
					Singleton Instance Created
[LOG] User logged in
[LOG] Database query executed
[LOG] Error: Out of memory

				
			

روش های پیاده‌سازی الگوی Singleton در #C

سه روش پرکاربرد برای پیاده‌سازی Singleton در #C وجود دارد که هرکدام مزایا و محدودیت‌های خودشان را دارند.

 

روش اول: Simple Singleton

نحوه پیاده سازی: متغیر استاتیک + سازنده خصوصی

				
					public sealed class Singleton {
    private static Singleton _instance;
    private Singleton(){}
    public static Singleton Instance
        => _instance ??= new Singleton();
}
				
			

روش دوم: Thread-Safe (Double-Check Locking)

نحوه پیاده سازی: lock + بررسی دو مرحله‌ای

				
					public sealed class Singleton {
    private static Singleton _instance;
    private static readonly object _lock = new();
    private Singleton(){}
    public static Singleton Instance {
        get {
            if (_instance == null) {
                lock (_lock) {
                    if (_instance == null)
                        _instance = new Singleton();
                }
            }
            return _instance;
        }
    }
}
				
			

روش سوم: Lazy Singleton

نحوه پیاده سازی: <Lazy<T با lambda

				
					public sealed class Singleton {
    private static readonly Lazy<Singleton>
        _instance = new(() => new Singleton());
    private Singleton(){}
    public static Singleton Instance
        => _instance.Value;
}
				
			

نکات حرفه‌ای برای بهینه‌سازی Singleton در #C

  • از sealed برای جلوگیری از ارث‌بری استفاده کنید.
  • اگر پروژه شما چند نخی (Multi-Thread) است، حتماً نسخه Thread-Safe یا Lazy را استفاده کنید.
  • Lazy<T> در #C پیش‌فرض Thread-Safe است و بهترین انتخاب برای کدهایی که کوتاهی و امنیت را توأم می‌خواهند.

سوالات متداول درباره الگوی طراحی Singleton در #C

الگوی Singleton یک روش طراحی نرم‌افزار است که اطمینان می‌دهد یک کلاس در طول اجرای برنامه فقط یک نمونه بسازد و همه بخش‌ها از همان نمونه استفاده کنند.

این کار برای مدیریت منابع مشترک مثل Logger، اتصال دیتابیس یا سیستم تنظیمات بسیار کاربردی است.

وقتی یک بخش از برنامه باید تنها یک نقطه مرکزی برای مدیریت داده یا منطق داشته باشد.

نمونه‌های رایج شامل سیستم‌های لاگ، مدیریت Session، استخر اتصال پایگاه داده و حافظه Cache هستند.

اگر احتمال چند نمونه‌ای شدن و مصرف اضافی منابع وجود دارد، Singleton راه‌حل مناسب است.

Singleton ساده در محیط‌های تک‌نخی مشکلی ندارد، اما در برنامه‌های چندنخی ممکن است چند نمونه همزمان ساخته شود.

در نسخه Thread-Safe با استفاده از lock (یا Lazy<T>) مطمئن می‌شویم که حتی با اجرای چند نخ هم فقط یک نمونه ساخته خواهد شد.

بله، Singleton نباید برای همه چیز استفاده شود.

اگر بیش‌ازحد به Singleton وابسته شوید، کدتان به شکل محکم کوپل شده (Tightly Coupled) درمی‌آید و تست‌نویسی را سخت می‌کند.

از آن فقط در مکان‌هایی استفاده کنید که واقعا نیاز به تنها یک نمونه دارید.

جمع‌بندی

📌 این ساختار Singleton یکی از پایه‌ای‌ترین ولی پراستفاده‌ترین patternهایی است که در پروژه‌های .NET، از اپلیکیشن‌های دسکتاپ گرفته تا وب‌سرویس‌های پربازدید، استفاده می‌شود.

📥 اگر سوالی داری در مورد الگوی Singleton در #C داری، در بخش کامنت‌ها بپرس.

میثم راد

من یه برنامه نویسم که حسابی با دیتابیس اوراکل رفیقم! از اونایی ام که تا چیزی رو کامل نفهمم،ول کن نیستم، یادگرفتن برام مثل بازیه، و نوشتن اینجا کمک می کنه تا چیزایی که یاد گرفتم رو با بقیه به شریک بشم، با هم پیشرفت کنیم.

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *