Adapter Pattern


ارسال در تاریخ ۲۱ بهمن,۱۳۹۵



ما سیستم خود را می سازیم، اما بخش های مختلف شبیه به هم نیستند. یک component داریم که به سه ورودی نیاز دارد با type های خاص و یک component دیگر داریم که به دو ورودی با type های خاص نیاز دارد. اولین فکری که به ذهنمان می رسد این است که بصورت جداگانه از این component ها استفاده کنیم و ورودی های مورد نیاز آن ها را تنظیم کنیم. اما این ایده خوبی نیست، بهتر است بگوییم این ایده وحشتناک است. برای حل این مشکل به یک لایه مترجم یا به اصطلاح translation احتیاج داریم و اینجا جایی است که الگوی Adapter مطرح می شود.

شبیه به یک translation layer یا لایه مترجم عمل می کند. Adapter در دنیای واقعی نیز وجود دارد. هنگامی که می خواهیم لپ تاپ خود را به projector وصل کنیم، بیشتر projector ها تنها ورودی VGA دارند، در حالیکه بیشتر لپ تاپ ها یک اتصال دیگری دارند، بنابراین برای استفاده از projector نیاز به یک Adapter داریم که اتصال را از یک فرمت به فرمت دیگری تبدیل کند.

با پیاده سازی الگوی طراحی Adapter، ما می توانیم با خیال راحت با کلاس های خارجی یا کتابخانه های خارجی و API ها کار کنیم.

در پروژه خود می خواهیم از component هایی که برای ارسال ایمیل نوشته شده اند استفاده کنیم، اما با یک API یکسان، یعنی اگر بخواهیم از یک component ارسال ایمیل دیگری استفاده کنیم نیازی به تغییر کد خودمان نداشته باشیم، Adapter این کار را برای ما انجام می دهد.

می خواهیم از دو کامپوننت Twilio که برای ارسال SMS می باشد و SendGrid که برای ارسال ایمیل است استفاده کنیم. یکی برای پیام متنی و دیگری برای ایمیل. در مرحله اول کدی که داریم بصورت زیر است و از هر کدام از این component ها بصورت زیر استفاده کرده ایم.

 

$twilio = new Service_Twilio('fake username','fake password');
$message = $twilio->account->messages->sendMessage(
	'+14085551234',		//The number to send from, your Twilio account
	'+122135679651',	//The number to send to
	"Hello world!"
);

$sendgrid = new SendGrid('fake username2','fake password');
$email = new SendGrid\Email();
$email->addTo('destination@example.com')->
	setFrom('sender@example.com')->
	setSubject('my great subject line')->
	setText('Hi')->
	setHtml('<strong>Hello world!</strong>');
$sendgrid->send($email);

در حالیکه این دو component خیلی شبیه به هم نیستند اما در واقع یک کار یکسان را انجام می دهند.

حالا چطور می توانیم اینجا از Adapter استفاده کنیم؟

چند مرحله را انجام می دهیم.

به جای کدهای بالا که در فایل index.php نوشتیم، کدهای زیر را قرار می دهیم.

include_once 'notify.php';
$notify = new Notify('username','password');
$notify->send('170354090212','123578719012','body of the message');

در واقع استفاده مستقیم از component های Twilio و SendGrid را از صفحه index.php حذف می کنیم. اگر به صورت مستقیم از این component ها استفاده کنیم، توسعه برنامه مان با دردسر خواهد بود یا خیلی زمان بر خواهد بود. اگر بخواهیم از یک component دیگر استفاده کنیم چه مشکلی پیش خواهد آمد؟

حالا یک کلاس با نام Notify ایجاد می کنیم که همه این تعاملات را برایمان انجام خواهد داد. 

ما هنوز به username و password احتیاج داریم، بنابراین این ها را می گیریم و object مان را آماده می کنیم. یعنی یک نمونه ایجاد می کنیم و سپس به آسانی متد send را اجرا می کنیم و این کلاس Notify است که تصمیم می گیرد از کدام متد send استفاده کند.

Class Notify{
	protected $username = '';
	protected $password = '';

	public function __construct($username,$password){
		$this->username = $username;
		$this->password = $password;
	}
	public function send($to,$from,$body,$subject=''){
		if ($subject == '') {
			return $this->sendSMS($to,$from,$body);			
		}

		return $this->sendEmail($to,$from,$body,$subject);
	}

	protected function sendSMS($to,$from,$body){
		$twilio = new Service_Twilio($this->username,$this->password);
		$message = $twilio->account->messages->sendMessage(
			$from,
			$to,
			$body
		);
		return $message;
	}

	protected function sendEmail($to,$from,$body,$subject){
		$sendgrid = new SendGrid($this->username,$this->password);
		$email = new SendGrid\Email();
		$email->addTo($to)->
			setFrom($from)->
			setSubject($subject)->
			setText($body)->
			setHtml($body);
		return $sendgrid->send($email);
	}
}

متدهای sendSMS و sendEmail بصورت protected تعریف شده اند، زیرا نمی خواهیم کاربران بصورت مستقیم به این متدها دسترسی داشته باشند. به یاد داشته باشید که Adapter طراحی شده است که جزئیات را مخفی کند و رابطه را آسان تر کند.


برای ارسال نظر لطفا وارد شوید.