دیزاین پترنها، Singletone

قبل از شروع مطلب پیش رو که در مورد الگوی طراحی سینگلتون ست، پیشنهاد میکنم پست قبلی با عنوان «دیزاین پترنها، تاریخچه و چرایی» رو مطالعه کنید.
الگوی طراحی سینگلتون (Singleton – یگانه) نوعی از دیزاین پترن کرییشنالست که در آن واحد تنها یک اینستنت (نمونه) از کلاس تولید میکند و دسترسی گلوبال رو برای آن فراهم میکند.
دیزاین پترنهای کرییشنال creational راجع به زمان و چگونگی ساخت آبجکتها صحبت میکنند.
این الگوی طراحی چه مشکلاتی رو حل میکند؟
یکی کنترل منابع اشتراکیست؛ مثل دیتابیس. فرض کنید شما در آن واحد نیاز دارید تنها یک کانکشن به دیتابیس زده شه و از تعدد آن جلوگیری شود.
دوم، ایجاد دسترسی گلوبال به یک اینستنس با قابلیت «فقط خواندن». ممکنست بگویید خب متغیر گلوبال تعریف میکنم. ولی اگر بخواهید یه متغیر گلوبال تعریف کنید هر کسی میتواند از هر نقطه برنامه، مقدارش رو عوض کند ولی در این ساختار جلوش گرفته شده یا حتی ممکنست قطعاتی از کد باشند که به این متغیر وابستهاند و بهتر است به صورت کپسوله در کلاس یک جا جمع باشند.
پیاده سازی الگوی طراحی سینگلتون چطوریه؟
همه کلاسها با الگوی طراحی سینگلون یه کانستراکتر دیفالت پرایوت دارند.
متد ساخت شی (در مثال زیر getInstance()
) که حکم کانستراکتر را دارد باید استاتیک باشد. این متد از یک کانستراکتور پرایوت ( که از بیرون – یعنی کلاینت – بهش دسترسی نیست) آبجکت را میسازد و در یک متغیر یا فیلد استاتیک ( در مثال instance$
) ذخیره میکند. تمام کال هایی که به این متد میشود قرارست کشی از همین آبجکت را برگرداند.
در این ساختار برای مقدار دهی اولیه کردن باید از Lazy Initialization استفاده شود. دیدم در ویکی فارسی ترجمه شده مقدار دهی اولیه کاهلانه (Too much farsi :D). آره خلاصه داشتم میگفتم، فارسیترش میشود: تا وقتی که به شی نیاز نیست نسازش تا هزینهی اضافی متحمل نشیم و برای این کار از متغیر پرایوت instance$
استفاده کردیم.
بریم سراغ پیادهسازی؟
اول از همه خود کلاس سینگلتون:
و در نهایت چیزی که کال میشود:
توضیحات مربوط به قطعه کد:
همانطور که میبینید فانکشن کانستراکتر را پرایوت کردیم تا از بیرون کلاس امکان چند باره ساخت شی نباشد و اگر خارج از کلاس امتحان کنید new Database()
میبینید که ارور عدم دسترسی خواهد داد. در این فانکشن میتونید مجموعه دستوراتی که لازمه هنگام اینستنس گرفتن از شی اجرا شه رو اضافه کنید: در اینجا مثلا باز کردن کانکشن دیتابیس.
متد getInstance()
وظیفه دارد بررسی کند اگر نمونه ای از کلاس وجود ندارد ایجادش کند و تحویل کلاینت دهد. شی $db1
و $db2
یکی هستند. دقت کنید که متغیر instance$
هم که مسئول نگهداری از «مقداردهی اولیه کاهلانه»ست باید پرایوت باشد که جلو خرابکاریهای احتمالی را بگیرد. حواستان باشه مثلا در PHP مجیک متدهایی مثل کلون، سریالایزو کلا هر چیزی که کانسپت سینگلتون بودن را از بین میبرد پرایوت کنید. در انتها باقی متدهایی که کلاینت قرارست در هنگام استفاده شی سینگلتون بهشان نیاز دارد و ازشون استفاده میکند را پابلیک کنید.
خیلیها معتقدند الگوی طراحی سینگلتون، آنتی پترنه
در پستهای بعدی در این مورد و دلایل موجود صحبت خواهیم کرد.
دیدگاهها