دیزاین پترن Singleton

دیزاین پترن Singleton

Creational Design Patterns

یکی از زیرشاخه های الگوهای طراحی، Creational Design Patterns است. این الگو راهی جهت ساخت و ایجاد اشیاء (object) از کلاس ها را ارائه میدهد. ساخت یک شیء با استفاده از new کردن آن کلاس در اصطلاح hard code کردن راه حل خوبی نیست و بهتر است از الگوهای طراحی Creational استفاده کرد.

Singleton Design Pattern (دیزاین پترن Singleton)

دیزاین پترن Singleton  یکی از زیرشاخه های الگوهای طراحی از نوع Creational است. یکی از پرکاربردترین دیزاین پترن ها، دیزاین پترن سینگلتون است. هدف این الگوی طراحی این است تا مطمئن شویم از یک کلاس، فقط و فقط یک شیء در کل برنامه وجود دارد.

میزان استفاده :  متوسط رو به بالا

نمونه ای که قرار است با هم بررسی کنیم، مثالی است از ساخت کلاسی برای لاگ زدن اطلاعات، خطاها و … .

فرض کنید کلاسی داریم که در آن قرار است در زمان بروز خطا، در کنسول خطا را با رنگ قرمز چاپ کند. برای این کار یک کلاس با نام Log داریم که در ساده ترین حالت یک پیغام به عنوان ورودی میگیرد.

public class Log
{
    public string Message { get; set; }
    public Log(string message)
    {
        Message = message;
    }
}

کلاس بعدی، کلاس Logger است که وظیفه آن نوشتن پیغام ارسالی از Log به خروجی کنسول است.

public class Logger
{
    public void AddLog(Log log)
    {
        if (log == null ||
            string.IsNullOrEmpty(log.Message) ||
            string.IsNullOrWhiteSpace(log.Message))
            return;
        Console.ForegroundColor = ConsoleColor.Red;
        Console.WriteLine(log.Message);
        Console.ForegroundColor = ConsoleColor.White;
    }
}

ما میخواهیم که مانند دیزاین پترن Factory تنها از یک کلاس به عنوان کارخانه جهت ایجاد شیء استفاده کنیم. اما تفاوت اینجاست که میخواهیم در کل برنامه تنها یک شیء از این کلاس وجود داشته باشد.

کلاس LoggerContext وظیفه نگهداری این یک شیء را بر عهده خواهد داشت.

internal class LoggerContext
{
    private static Logger logger;

    private LoggerContext()
    {

    }

    public static Logger GetLogger()
    {
        if (logger == null)
            logger = new Logger();
        return logger;
    }
}

اگر به کد توجه کنید، یک شیء از نوع Logger بصورت static تعبیه شده اما مقدار دهی نشده است.

سازنده کلاس بصورت private است تا از بیرون از کلاس نتوان شیئی از آن ساخت.

متدی جهت دریافت این یک شیء با نام GetLogger نوشته شده که بررسی میکند اگر بار اول درخواست دریافت شیء را داده بودیم آن را ایجاد کند و در متغیر استاتیک ذخیره نماید و سپس آن را برگرداند. درصورتی که برای بار دوم به بعد بود، تنها همان مقداری که قبلا ایجاد شده بود باز گردانده میشود.

این نوع پر کردن متغیر را در دیزاین پترن سینگلتون، Lazy Load میگویند. نوع دیگر آن که Eager Load میباشد، به این صورت است که در همان لحظه اول، متغیر استاتیک پر میشود و با صدا زدن متد GetLogger تفاوتی برای بار اول و دوم به بعد ندارد. مانند کد زیر :

internal class LoggerContext
{
    private static Logger logger = new Logger();

    private LoggerContext()
    {

    }

    public static Logger GetLogger()
    {
        return logger;
    }
}

حال نوبت به نوشتن متد main برنامه و نحوه استفاده میرسد.

static void Main(string[] args)
{
    try
    {
        var logger = LoggerContext.GetLogger();
        logger.AddLog(new Log("Log 1"));
        Console.WriteLine(logger.GetHashCode());

        var logger2 = LoggerContext.GetLogger();
        logger2.AddLog(new Log("Log 2"));
        Console.WriteLine(logger2.GetHashCode());
    }
    catch (Exception ex)
    {
        ShowError(ex.Message);
    }
    Console.ReadLine();
}

همانطور که مشاهده میشود، متغیر logger از کلاس LoggerContext با فراخوانی متد GetLogger اقدام به ساخت و دریافت شیء میکند. اما متغیر logger2 زمانی که میخواهد همین کار را بکند، از همان شیء Logger که در فراخوانی بار اول ایجاد شده بود استفاده میکند و این متغیر تنها یک بار در رم ساخته شده و از همان یک شیء در سراسر برنامه و لایه ها استفاده میشود.

از موارد استفاده دیزاین پترن Singleton (سینگلتون) میتوان به موارد زیر اشاره کرد:

  • ایجاد context جهت اتصال به دیتابیس
  • عملیات caching
  • Thread pool ها
  • Logging
singleton-design-pattern

پرینت صفحه دانلود این آموزش

هولوسن

با من یاد بگیر

آموزش های بیشتر در وبسایت هولوسن : https://holosen.net

بدون نظر

**پرسش و پاسخ** سوال خود مطرح کنید.
امتیاز شما*