الگوی یگانه

از ویکی‌پدیا، دانشنامهٔ آزاد
پرش به: ناوبری، جستجو

الگوی یگانه یک الگوی طراحی در مهندسی نرم‌افزار است. این الگو ایجاد شیء از یک کلاس را محدود می‌سازد. این الگو زمانی مفید است که در سرتاسر سیستم تنها به یک نمونه از آن کلاس نیاز باشد. این مفهوم عموماً به سیستم‌هایی که با یک یا تعداد محدودی نمونه بهینه‌تر کار می‌کنند، نیز تعمیم داده می‌شود. واژهٔ آن از مفهوم ریاضی یگانه (Singleton) برگرفته شده است.

انتقادهایی به استفاده از الگوی یگانه وجود دارد. برخی آن را یک ضدالگو تلقی می‌کنند، زیرا بیش از حد استفاده می‌شود، محدودیت‌های نابجایی را زمانی که تنها یک نمونه از کلاس لزوماً مورد نیاز نیست، به وجود می‌آورد و حالت سراسری را به یک برنامه القا می‌کند. فریم‌ورک‌ها و سیستم‌عامل‌هایی مانند اندروید زمانی که نیازمند تخصیص حافظه به برنامه‌ای دیگر باشند، به صورت غیرمنتظره اقدام به زباله روبی اشیاء یگانه می‌کنند.

موارد استفاده[ویرایش]

* الگوهای کارخانهٔ انتزاعی، سازنده و نمونهٔ اولیه می‌توانند در پیاده‌سازی‌های خود از الگوی یگانه استفاده کنند.

  • اشیاء نماد خارجی معمولاً یگانه هستند زیرا تنها یک شیء نما خارجی مورد نیاز است.
  • اشیاء یگانه معمولاً نسبت به متغیرهای سراسری ترجیح داده می‌شوند، زیرا:
  • فضای نام سراسری را با متغیرهای نالازم آلوده نمی‌کنند.
  • اجازه تحصیص و ایجاد اشیاء به صورت تنبل را می‌دهند، درحالیکه متغیرهای سراسری در بسیاری از زبان‌ها از همان ابتدای برنامه شروع به گرفتن منابع می‌کنند.

زبان مدل‌سازی یکپارچه[ویرایش]

Singleton.png

پیاده‌سازی[ویرایش]

پیاده‌سازی الگوی یگانه باید قواعد تک شیء بودن و دسترسی سراسری را ارضا کند. این نیازمند یک سازوکار برای دسترسی به عضو یگانهٔ کلاس بدون ایجاد یک شیء از آن کلاس است. نحوه پیاده‌سازی به این گونه است که کلاس باید یک متد داشته باشد تا یک شیء از همان کلاس را در صورتی که قبلاً ساخته نشده است، برگرداند. برای اطمینان از اینکه نمونهٔ دیگری از این کلاس قابل ایجاد نیست باید دسترسی به constructor کلاس خصوصی باشد. به تفاوت بین یک نمونهٔ ایستا از کلاس و نمونه یگانه توجه کنید: گرچه نمونه یگانه می‌تواند از طریق ایجاد یک نمونه ایستا پیاده‌سازی شود ولی می‌تواند تا زمانی که نیازی به آن پیدا نشده، ساخته نشود و منابع را مصرف نکند. پیاده‌سازی الگوی یگانه در برنامه‌هایی که قابلیت چند ریسه‌ای دارند نیازمند دقت بیشتری است. اگر دو ریسه همزمان وارد متد مربوط به درخواست شیء یگانه شوند و شیء یگانه هنوز ایجاد نشده باشد، تنها یکی از آن دو ریسه باید شیء را ایجاد کند. راه حل این مسئله استفاده از انحصار متقابل در هنگام ایجاد شیء یگانه است.

مثال[ویرایش]

مثال‌هایی که به زبان جاوا در زیر آمده‌اند همگی از لحاظ چندریسه بودن مطمئن هستند ولی از لحاظ نسخهٔ جاوا و بارگیری تنبلانه (Lazy Loading) فرق می‌کنند.

ایجاد تنبلانه[ویرایش]

public class SingletonDemo {
    private static volatile SingletonDemo instance;
    private SingletonDemo() { }

    public static SingletonDemo getInstance() {
        if (instance == null ) {
            synchronized (SingletonDemo.class) {
                if (instance == null) {
                    instance = new SingletonDemo();
                }
            }
        }

        return instance;
    }
}

در محیط چند ریسه‌ای:

public class SingletonDemo {
    private static SingletonDemo instance = null;
    private SingletonDemo() { }

    public static synchronized SingletonDemo getInstance() {
        if (instance == null) {
            instance = new SingletonDemo();
        }

        return instance;
    }
}