الگوی طراحی سینگلتون — راهنمای جامع
در الگوی طراحی سینگلتون (Singleton) تعداد وهلههای کلاس محدود به یک وهله میشود. الگوهای طراحی مختلفی در زمینه نرمافزار وجود دارند. این الگوها راهحلهایی برای مسائل خاص ارائه میکنند که در توسعه نرمافزار به صورت مکرر پیش میآیند. در این مقاله قصد داریم الگوی طراحی سینگلتون و شیوه بهکارگیری آن را توضیح دهیم.
ایده اساسی الگوی طراحی سینگلتون
در محیط برنامهنویسی، الگوی سینگلتون به یک الگوی طراحی نرمافزار گفته میشود که میزان وهلهسازی از یک کلاس را به عدد یک محدود میسازد. این حالت در مواردی که بخواهیم دقیقاً یک شیء اقدام به هماهنگسازی اقدامات در سیستم بکند مفید خواهد بود. این اصطلاح از مفهوم ریاضیاتی سینگلتون ناشی میشود.
در الگوی سینگلتون باید مطمئن شویم که تنها یک وهله وجود دارد و یک نقطه دسترسی سراسری برای دسترسی به آن ارائه کنیم.
ویژگی اصلی این الگو آن است که تنها یک شیء منفرد از هر کلاس وهلهسازی میشود. ضمناً نقطه ورودی منفردی برای کلاس ایجاد میشود که عموماً با استفاده از متد accessor مانند getInstance مورد استفاده قرار میگیرد.
اگر بخواهیم جمعبندی کنیم، آداپتر شیء یعنی سینگلتون شامل یک وهله از کلاسی است که آن را پوشش میدهد. نمودار UML این الگو به صورت زیر است:
کلاس Singleton کلاس منفردی است که خصوصیت خاص خود را به نام uniqueInstance دارد و یک وهله از کلاس Singleton را ذخیره میکند. سازنده کلاس، خصوصی است و میتوانید از طریق متد accessor که باید getInstance باشد به آن دسترسی یابید.
متد accessor مسئول بازگشت این وهله منفرد در صورت وجود است. این متد در حالتی که هنوز وهلهای ایجاد نشده باشد، اقدام به وهلهسازی میکند.
الگوی سینگلتون باید در موارد زیر مورد استفاده قرار گیرد:
- باید یک وهله منفرد از کلاس وجود داشته باشد و این کلاس باید از سوی کلاینتها از یک نقطه دسترسی شناختهشده برایشان قابل دسترسی باشد.
- کلاس سینگلتون باید به وسیله وراثت بسط یابد و کلاینتها باید بتوانند کلاسهای بسط یافته را بدون ایجاد تغییری در آن مورد استفاده قرار دهند.
الگوی سینگلتون چندین مزیت دارد که به صورت زیر جمعبندی میشوند:
- کنترل کاملی روی چگونگی و زمان دسترسی کلاینتها به یک وهله سینگلتون وجود دارد. دسترسی کنترلشدهای دارید، زیرا کلاس سینگلتون وهلهاش را کپسولهسازی میکند.
- در مواردی که بخواهید تعداد وهلههایی که از یک کلاس ایجاد میشود را جهت حفظ منابع سیستم، محدود سازید مفید است.
- الگوی سینگلتون یک بهینهسازی نسبت به متغیرهای سراسری محسوب میشود زیرا از آلوده شدن فضای نام با متغیرهای سراسری که تنها وهلههای سینگلتون را ذخیره میسازند جلوگیری میکند.
- استفاده از کد، درک آن و تستش آسانتر است، زیرا سینگلتون کد را ساده میکند.
در این بخش شیوه پیادهسازی این الگو را با استفاده از زبان جاوا اسکریپت/تایپ اسکریپت مورد بررسی قرار میدهیم. در این مورد مسئلهای ساختهایم که در آن کلاسی به نام DatabaseConnection وجود دارد. این کلاس دو خصوصیت به نامهای configuration و getUniqueIdentificator تعریف میکند. این کلاس اتصالی به پایگاه داده برقرار میسازد. DatabaseConnection از سوی چندین کلاینت (client1 و client2) مورد استفاده قرار میگیرد. نمودار UML زیر سناریویی را نمایش میدهد که توصیف کردیم.
کد Client به صورت زیر است:
هر کلاینت یک اتصال جدید به پایگاه داده ایجاد کرده و شناسه یکتایی برای هر اتصال درخواست میکند. یکی از نتایج عمده این معماری استفاده از منابع زیادتر از مقدار لازم است.
کلاس DatabaseConnection به صورت زیر است:
در کلاس قبلی میشد دید که تنها یک خصوصیت خصوصی میتواند در پیکربندی پایگاه داده حضور داشته باشد و شناسه یکتا با استفاده از خصوصیت عمومی مورد دسترسی قرار میگیرد. در نهایت کد نمونه برای تعامل به صورت زیر است:
نتیجه به دست آمده در تصویر زیر نمایش یافته است:
چنان که میبینید هر وهله از پایگاه داده مربوط به وهلههای متفاوتی است و شناسه یکتای مختلفی نیز دارد، در حالی که دقیقاً وظیفه یکسانی اجرا میکنند. در واقع هوشمندانهترین روش میتوانست این باشد که یک وهله برای ایجاد اتصال داشته باشیم.
راهحل این مسئله، استفاده از الگوی سینگلتون است که تنها یک وهله از کلاس ایجاد میکند. نمودار UML زیر با استفاده از الگوی آداپتر طراحی شده است:
کد مرتبط با DatabaseConnection به صورت زیر است:
تنها نقطه دسترسی به وهله با استفاده از متد استاتیک getDatabaseConnection است که وهله جدیدی در صورت عدم وجود میسازد و یا در صورت وجود آن را به دست میآورد. به این طریق کلاینتها اندکی تغییر مییابند تا به جای ایجاد وهلههای خاص خود، از این وهله استفاده کنند:
نتیجه پس از تغییرات در اجرای برنامه در تصویر زیر نمایش یافته است:
برای اجرای دو مثال نمایش یافته در اینجا دو اسکریپت npm پس از بهکارگیری الگوی سینگلتون نوشتهایم:
npm run example1-problem npm run example1-singleton-solution1
مثال جالب دیگر که با استفاده از الگوی سینگلتون حل میشود، مواردی هستند که چندین کلاس باید به صورت سینگلتون باشند. برای نمونه یک مجموعه قهرمانان مانند سوپرمن، بتمن سینگلتون هستند. در نمودار UML زیر این موقعیت را میبینید:
کد مرتبط با کلاینتها به صورت زیر است:
سپس قهرمانهای خود را میسازیم که یکتا خواهند بود. قبل از هر چیز یک اینترفیس مشترک برای اطلاعاتی که هر یک شامل خواهند بود طراحی میکنیم:
قهرمانها یکتا هستند، اما خصوصیتها و متدهای مشترکی دارند. به همین جهت یک کلاس والد به نام HeroBase تعریف کردهایم که شامل ویژگیهای مشترک هر دو مورد Spiderman و Batman میشود. این کلاس به صورت زیر است:
هر دو قهرمان بتمن و سوپرمن الگوی سینگلتون را در ساختمان خودشان پیادهسازی کردهاند و ارجاعی به تنها شیء هر کلاس نگهداری میکنند. این کلاسها به صورت زیر هستند:
در نهایت کد نمونه برای تعامل به صورت زیر است:
نتیجه به دست آمده مانند تصویر زیر است:
اسکریپت npm زیر را ایجاد کردیم که مثال نمایش یافته را پس از اعمال الگوی سینگلتون اجرا میکند:
npm run example2-singleton-solution1
سخن پایانی
این الگوی سینگلتون میتواند از پیچیدگی در پروژهها جلوگیری کند، زیرا کنترل کاملی روی وهلهسازی یک کلاس به دست میآید و یک نقطه ورودی منفرد شناختهشده برای کلاینتها ایجاد میشود. بهعلاوه این الگویی است که در منابع سیستم صرفهجویی میکند، زیرابه جای وهلهسازی یک مجموعه از کلاسها که وظیفه یکسانی را اجرا میکنند، یک وهله مفرد از آن کلاس را مورد استفاده قرار خواهد داد. با این حال این الگو شهرت بسیار منفی کسب کرده است و حتی گاهی ضد الگو نامیده میشود، زیرا متغیرهای سراسری که ایجاد میکند میتوانند از هر کجای کد مورد دسترسی قرار گرفته و تغییر یابند.
مهمترین نکته در مورد این الگو آن است که نباید آن را صرفاً به صورتی که در این مقاله نشان دادیم پیادهسازی کنید، بلکه باید مشکلی که این الگوی خاص میتواند حل کند را به دقت شناسایی کرده و مواردی که نباید آن را پیادهسازی کرد را بشناسید. این نکتهای حیاتی است زیرا پیادهسازی آن وابستگی زیادی به زبان برنامهنویسی مورد استفاده دارد.
اگر این نوشته برای شما مفید بوده است، آموزشهای زیر نیز به شما پیشنهاد میشوند:
- مجموعه آموزشهای برنامهنویسی
- آموزش الگوهای طراحی (Design Patterns) در پایتون (Python)
- مجموعه آموزشهای JavaScript (جاوا اسکریپت)
- الگوهای طراحی مختلف در جاوا اسکریپت — به زبان ساده
- برنامه نویسی Kotlin — ایجاد الگوهای طراحی اندروید با کوتلین
==