آشنایی با الگوی طراحی Singleton

الگوهای طراحی مختلفی وجود دارند که به عنوان یک برنامه نویس باید نحوه استفاده از آنها را بلد باشید.
در این آموزش با پیاده سازی الگوی طراحی Singleton در زبان برنامه نویسی دارت و فلاتر آشنا میشویم.
از الگوی Singleton زمانی استفاده میکنیم که میخواهیم مطمئن شویم فقط و فقط یک نمونه از کلاس مورد نظر ساخته خواهد شد نه بیشتر و به شکل سراسری به آن دسترسی داشته باشیم.
برای مثال در کلاس های مدل یا ارتباط با دیتابیس و سرور از این الگو استفاده بیشتر استفاده میشود.
در این موارد بخش های مختلف یک برنامه نیاز دارند تا با این کلاس ها کار کنند و نمونه مخصوص به خود را از کلاس ایجاد کند در این حالت Singleton یک روش کد نویسی تمیز تری را ارائه میکند که از مصرف حافظه بیشتر جلوگیری میکند.
در این روش نمونه سازی از کلاس فقط در ابتدای دسترسی به کلاس انجام می شود. این کار باعث انعظاف پذیری و قابلیت گسترش کد ها را به ما میدهد.
پیاده سازی Singleton
تصویر زیر دیاگرام ساده ای از پیاده سازی الگوی طراحی Singleton می باشد که میتونید مشاهده کنید.

یک کلاس معمولی از نوع Singleton دارای یک متغیر خصوصی یا استاتیک هست که به آبجکتی از این کلاس اشاره میکند.
متد سازنده یا کانستراکتور در این نوع کلاس ها معمولا هیچ پارامتری دریافت نمیکنند.
اگر این متد پارامتر ورودی دریافت کند در آن صورت امکان ساخت نمونه های متفاوت از هم وجود خواهد داشت که به طور کلی فلسفه ساخت کلاس های Singleton زیر سوال میرود.
متد getInstance() هم عموما به شکل استاتیک تعریف می شود و به عنوان دروازه ای برای دست یافتن به نمونه ای از کلاس عمل میکند.
کد زیر یک نوع پیاده سازی این طراحی در زبان دارت می باشد.
class Singleton {
static Singleton _instance;
Singleton._internal();
static Singleton getInstance() {
if (_instance == null) {
_instance = Singleton._internal();
}
return _instance;
}
}
در ابتدا یک متغیر استاتیک به نام _instance از نوع کلاس مورد نظر ایجاد میکنیم.
برای دسترسی به این نمونه از کلاس باید از متد getInstance() در بقیه کلاس ها استفاده شود اگر این متد نتواند یک نمونه از این کلاس را پیدا کند با استفاده از متد سازنده به نام _internal یک نمونه از کلاس ایجاد میکند.
اگر در قسمتی از برنامه نیاز به دسترسی به این نمونه از کلاس داشته باشید میتوند به شکل زیر عمل کنید.
final singleton = Singleton.getInstance();
در ادامه با استفاده از دستورات زبان دارت میتوانیم کلاس های singleton را به شکل ساده تری نیز پیاده سازی کنیم. به مثال زیر توجه کنید.
در این کد بجای ایجاد متد getInstance() از قابلیت getter در دارت استفاده کرده ایم.
class Singleton {
static Singleton _instance;
static get instance {
if (_instance == null) {
_instance = Singleton._internal();
}
return _instance;
}
Singleton._internal();
}
کد باعث خوانایی بیشتر برنامه میشود و برای استفاده از آن دیگر نیازی به قرار دادن پرانتز ندارید.
final singleton = Singleton.instance;
به نظرتون راهی برای ساده تر کردن این کد وجود دارد؟
برای ساده تر کردن میتونیم از قابلیت متد سازنده factory در زبان دارت هم استفاده کنیم که کد ما به شکل زیر تغییر میکند.
class Singleton {
static Singleton _instance;
Singleton._internal();
factory Singleton() {
if (_instance == null) {
_instance = Singleton._internal();
}
return _instance;
}
}
از کانستراکتور factory زمانی استفاده میکنیم که متد سازنده کلاس همیشه نمونه جدیدی از کلاس ایجاد نمیکند مثل متد سازنده عادی.
در این مثال متد سازنده ما فقط یکبار نمونه جدید میسازد و در دفعات بعدی این نمونه ساخته شده را برمیگرداند.
برای استفاده از این کلاس کاربر به شکل زیر میتواند عمل کند.
final singleton = Singleton();
مثال بالا دقیقا مثل زمانی هست که یک نمونه معمولی از کلاس میخواهیم ایجاد کنیم.
اما بازهم میتونیم از امکانات زبان دارت استفاده کنیم و این کد را کوتاه تر کنیم آن هم با استفاده از دستور چک کردن null بودن از طریق دو علامت سوال به شکل پایین.
class Singleton {
static Singleton _instance;
Singleton._internal() {
_instance = this;
}
factory Singleton() => _instance ?? Singleton._internal();
}
روش فراخوانی این کلاس مثل نمونه قبلی است و فرقی ندارد فقط پیاده سازی آن کوتاه تر شده است.
امیدوارم این که آموزش براتون مفید بوده باشه.
ترجمه از Dart Academy
دیدگاهتان را بنویسید