ava
ava
خواندن ۱ دقیقه·۳ سال پیش

دیزاین پترن Singleton

اینجا سعی میکنم توضیح کوتاهی بنویسم از آنچه که خودم یادگرفتم و فهمیدم، بنابراین اگر اشتباهی دیدید برام کامنت بزارید تا من هم بهتر یاد بگیرم. توضیح بدم که من کارم برنامه نویسی وب هست و طبیعاتا مثال‌هایی که به ذهنم میاد مرتبط با کارم هست و کدی که مثال میزنم هم پی‌اچ‌پی هست.
این دیزاین پترن دو تا مشکل رو حل میکنه، پس اولین مشکلی که خودش داره اینه که سینگل ریسپانسیبیلیتی رو رعایت نمیکنه و به جای یک کار دو تا کار انجام میده. اما چه مشکلاتی رو حل میکنه؟ ۱- اطمینان میده که از کلاس یک instance ساخته شده. ۲- از همه جای کد به اون instance دسترسی داریم

یه مثال که به نظر خودم کاربرد داره اینه که مثلا اگر یه سایت چند زبانه داشته باشیم و بخوایم همه متن‌های سایت رو با ترجمه به زبان کنونی سایت نشون بدیم، میتونیم ازین دیزاین‌پترن استفاده کنیم.
به این شکل که مثلا یه کلاس Locale داشته باشیم و زبان رو ست کنیم توش و هرجای سیستم زبان رو get کردیم زبان سیستم رو نشون بده
در مثال پایین ما دوبار instance از کلاس Locale ساختیم ولی وقتی مقدار را در instance اول تغییر میدیم مقدار آن در instance دوم هم تغییر میکنه. در واقع هر دو instance ما یکی هست با دو نام متفاوت.

Locale.php <?php
class Locale {
private static $instances = [];
protected $defaultLanguage = 'en'; private $locale = '';
public static function getInstance(): Locale
{
$class = static::class;
if (!isset(self::$instances[$class])) {
self::$instances[$class] = new static(); }
return self::$instances[$class]; }
public function getLocale(){
return $this->locale;
}
public function setLocale(String $iso2 = null){
$this->locale = $iso2 ?? $this->defaultLanguage;
}
}


index.php <?php use Locale; $locale = Locale::getInstance();
$locale->setLocale();
var_dump($locale->getLocale()); // return value is : 'en'
$locale->setLocale('de');
$locale2 = Locale::getInstance();
var_dump($locale2->getLocale()); // return value is: 'de'

یکی دیگه از مشکلای اساسی که این دیزاین پترن داره اینه که با یونیت تست راحت نمیشه تستش کرد، چون قراره تو سیستم یه بار ساخته باشه و همه جا ازش استفاده بشه پس اگه تو یه تستی تغییر کنه یا ارور داشته باشه همه تستا رو خراب میکنه.

فرض کنیم تو یکی از تست‌ها زبان رو به آلمانی تغییر دادیم

$locale = Locale::getInstance();
$locale->setLocale('de');
$this->assertSame($locale->getLocale(), 'de');

در این صورت اگر تو یه تست دیگه زبان رو بگیریم میبینیم که زبان اون هم به آلمانی تغییر کرده

phpبرنامه‌نویسیدیزاین پترنdesign patternsingleton
شاید از این پست‌ها خوشتان بیاید