آموزش دیزاین پترن Singleton  در php

آموزش دیزاین پترن Singleton در php

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

همانطور که می دانید دیزاین پترن ها در اصل روش  می باشند که توسط دیگربرنامه نویسان برای کوتاه کردن و بهینه سازی کد های برنامه نویسان ایجاد شده اند. در این مطلب ما قصد داریم در مورد دیزاین پترن singleton در php  صحبت و روش استفاده از آن را توضیح دهیم.

  

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

البته الگوی singleton به دلیل محدودیت در ایجاد مجدد شی در هنگام آزمایش واحد های پیچیده بدنام می باشد. اما هنوز بسیار مفید می باشد، برای نمونه هنگامی که شما نیاز به استفاده از منابع مشترک دارید این الگو بسیار می تواند مفید باشد. برای نمونه با این الگو می تواند بخش log و ذخیره سازی را اجرایی کرد.

در این آموزش ما ابتدا یک کلاس بنام singleton خواهیم ساخت و سپس دو کلاس دیگر خواهیم ساخت که با استفاده از کلاس singleton تنها یک بار اجرا خواهند شد. 

 

یک فایل بنام index.php ایجاد نمایید و کد های زیر را در آن قرار دهید:

<?php


class Singleton
{
	/**
	 * The actual singleton's instance almost always resides inside a static
	 * field. In this case, the static field is an array, where each subclass of
	 * the Singleton stores its own instance.
	 */
	private static $instances = [];
	
	/**
	 * Singleton's constructor should not be public. However, it can't be
	 * private either if we want to allow subclassing.
	 */
	protected function __construct() { }
	
	/**
	 * Cloning and unserialization are not permitted for singletons.
	 */
	protected function __clone() { }
	
	public function __wakeup()
	{
		throw new \Exception("Cannot unserialize singleton");
	}
	
	/**
	 * The method you use to get the Singleton's instance.
	 */
	public static function getInstance()
	{
		$subclass = static::class;
		if (!isset(self::$instances[$subclass])) {
			// Note that here we use the "static" keyword instead of the actual
			// class name. In this context, the "static" keyword means "the name
			// of the current class". That detail is important because when the
			// method is called on the subclass, we want an instance of that
			// subclass to be created here.
			
			self::$instances[$subclass] = new static;
		}
		return self::$instances[$subclass];
	}
}


class Logger extends Singleton
{
	/**
	 * A file pointer resource of the log file.
	 */
	private $fileHandle;
	
	/**
	 * Since the Singleton's constructor is called only once, just a single file
	 * resource is opened at all times.
	 *
	 * Note, for the sake of simplicity, we open the console stream instead of
	 * the actual file here.
	 */
	protected function __construct()
	{
		$this->fileHandle = fopen('pishroapp.txt', 'w');
		
	}
	
	/**
	 * Write a log entry to the opened file resource.
	 */
	public function writeLog(string $message): void
	{
		$date = date('Y-m-d');
		fwrite($this->fileHandle, "$date: $message\n");
	}
	
	/**
	 * Just a handy shortcut to reduce the amount of code needed to log messages
	 * from the client code.
	 */
	public static function log(string $message): void
	{
	 
		$logger = static::getInstance();
		$logger->writeLog($message);
	}
}

/**
 * Applying the Singleton pattern to the configuration storage is also a common
 * practice. Often you need to access application configurations from a lot of
 * different places of the program. Singleton gives you that comfort.
 */
class Config extends Singleton
{
	private $hashmap = [];
	
	public function getValue(string $key): string
	{
		return $this->hashmap[$key];
	}
	
	public function setValue(string $key, string $value): void
	{
		$this->hashmap[$key] = $value;
	}
}


Logger::log("Started!");

// Compare values of Logger singleton.
$l1 = Logger::getInstance();
$l2 = Logger::getInstance();
if ($l1 === $l2) {
	Logger::log("Logger has a single instance.");
} else {
	Logger::log("Loggers are different.");
}

// Check how Config singleton saves data...
$config1 = Config::getInstance();
$login = "test_login";
$password = "test_password";
$config1->setValue("login", $login);
$config1->setValue("password", $password);
// ...and restores it.
$config2 = Config::getInstance();
if ($login == $config2->getValue("login") &&
	$password == $config2->getValue("password")
) {
	Logger::log("Config singleton also works fine.");
}

Logger::log("Finished!");


	

 

توضیح کد بالا:

 

کلاس Singleton:

 

متد (getInstance):

این متد کار اصلی را در کلاس های singleton انجام می دهد، به این صورت که ابتدا چک می کند اگر از کلاس مورد نظر نمونه ای موجود باشد، نمونه موجود را برگشت می دهد در غیر این صورت یک نمونه جدید خواهد ساخت.

 

کلاس های Logger و Config:

این کلاس ها از کلاس singleton ارث بری می کنند بنابراین شما می توانید با متد getInstance این کلاس را ایجاد نمایید. و به راحتی از متد های آن استفاده کنید.

 

حال بصورت زیر از دو کلاس زیر استفاده کرده ایم:

// Check how Config singleton saves data...
$config1 = Config::getInstance();
$login = "test_login";
$password = "test_password";
$config1->setValue("login", $login);
$config1->setValue("password", $password);
// ...and restores it.
$config2 = Config::getInstance();
if ($login == $config2->getValue("login") &&
	$password == $config2->getValue("password")
) {
	Logger::log("Config singleton also works fine.");
}

Logger::log("Finished!");

 

همانطور که می بینید ما از کلاس Config دو نمونه ساخته ایم و سپس با یک دستور if مقادیر نمونه های اول و دوم رو چک کرده ایم. 

البته کلاس log نیز کار لاگ کردن پروسه را در یک فایل بنام pishroapp.txt بر عهده دارید که پس از اجرای کدهای بالا خروجی این فایل بصورت زیر خواهد بود:

2019-08-08: Started!
2019-08-08: Logger has a single instance.
2019-08-08: Config singleton also works fine.
2019-08-08: Finished!

که این نشان می دهد که ما تنها یکبار از کلاس Config نمونه ساخته ایم.

 

پس بطور خلاصه کارِ کلاس singleton جلوگیر از ایجاد نمونه های متعدد در پروژه می باشد.

 

امیدوارم این آموزش برای شما مفید باشه. 

درصورتی که سوالی دارید از بخش نظرات ارسال کنید.


برچسب ها:


دسته بندی ها:

پی اچ پی

ارسال نظر

برای اطلاع از پاسخ به نظر شما می توانید ایمیل یا شماره موبایل خود را وارد نمایید. *

ایمیل و شماره موبایل شما کاملا مخفی خواهد ماند و در سایت نمایش داده نخواهد شد. *

اگر نظری برای این مطلب ارسال شد از طریق ایمیل مرا اطلاع بده!
لسیت نظرات
هنوز برای این مطلب نظری ارسال نشده است!