آموزش دیزاین پترن Strategy و پیاده سازی آن با مثال

الگو های طراحی در برنامه نویسیسلام دوستان .قصد دارم الگو های طراحی یا همون design pattern ها در برنامه نویسی را به صورت ساده و کاربردی و همراه با مثال توی چند پست توضیح بدم .حالا اصلا الگو های طراحی چی هستند ؟ خب در طی زمان های گذشته تا به امروز بعضی مواقع برنامه نویس ها در هنگام کد نویسی به یک سری مشکلات و پیچیدگی هایی داخل کد نویسی بر میخوردند که باعث میشد ساعت ها فکر کنند و آزمون و خطا کنند و روش های مختلف در ساختار کد رو بررسی کنند تا بتونند بهترین روش رو به کار بگیرند و اون مساله یا الگوریتم رو پیاده سازی کنند . کم کم این مشکلات و روش های حل خیلی رایج و شناخته میشن و در طی زمان باعث میشه برنامه نویس ها اون روش های حل مساله رو داکیومنت کنن و در کیس مورد نظر خودش استفاده کنند . در واقع دیزاین پترن ها یک سری روش حل مساله هستند که هر کدومشون یک پیچیدگی را حل میکنند و باعث میشن کار برنامه نویس راحت تر بشه . شما باید با مطالعه کردن اون ها یاد بگیرید که هر کدومشون تو چه مواقعی استفاده میشن و چه کاری رو آسون میکنند .دیزاین پترن ها اصلا وابسته به زبان برنامه نویسی خاصی نیستند و اصلا مهم نیست که شما با چه زبانی دارید کد میزنید . شما فقط باید کاربرد هر کدوم رو بدونید و بدونید چه وقتی از کدوم استفاده کنید . این مهم ترین چیزه . من برای مثال زدن توی آموزش ها از زبان PHP استفاده میکنم ولی شما میتونید با یه سرچ ساده پیاده سازی هر دیزاین پترنی رو داخل هر زبانی پیدا کنید .خب بریم سراغ اولین الگوی طراحی که خیلی کاربردی هست . آموزش الگوی طراحی Strategy :از این الگو زمانی استفاده میکنیم که بخوایم یه کاری رو به چند روش پیاده سازی کنیم . چند تا مثال میزنم . برای مثال : لاگین کردن کاربر داخل سایت ! لاگین کردن به چندین روش صورت میگیره . مثلا لاگین کردن با ایمیل . لاگین کردن با ارسال کد احراز هویت بوسیله پیامک به کاربر . لاگین کردن با گیت هاب و یا لینکداین . در واقع ما چندین روش رو برای لاگین کردن در نظر میگیرم.مثال بعدی پیاده سازی درگاه پرداخت هست . مثلا پرداخت با درگاه ملی . پرداخت با درگاه صادرات . پرداخت با درگاه زرین پال و غیره . در واقع ما سیستم پرداخت رو میتونیم به چند روش پیاده سازی کنیم و فقط نمیخایم از یک درگاه استفاده کنیم.در این مواقع باید از الگوی طراحی استراتژی استفاده کنیم .برای پیاده سازی مواد لازم چیه ؟ اول از همه یک Interface لازم داریم . در داخل این اینترفیس استراتژی خودمون رو تعیین میکنیم. بعد به تعداد روش هایی که میخایم پیاده سازی کنیم کلاس ایجاد میکنیم و اون کلاس هارو ملزم میکنیم تا از قانون و اینترفیس ما پیروی کنند و در واقع یک استراتژی واحد را (که همون اینترفیسمونه) رو implement کنن.مثال : فرض کنید یه سایت داریم و میخایم هر بار کاربر جدیدی داخل سایت عضو شد به اون خوش آمد بگیم . چند روش داریم ؟روش اول : خوش آمد گویی با ارسال یک پیامک به شماره تماس کاربر روش دوم :‌ خوش آمد گویی با ارسال ایمیل خوش آمدگویی به کاربر دو روش بالا رو میتونیم پیش بینی و پیاده سازی کنیم و از هرکدام خواستیم استفاده کنیم . ممکنه امروز بخایم فقط با پیامک خوش آمد بگیم . ولی ممکنه فردا فقط بخوایم با ایمیل خوش آمد بگیم . خب بریم سراغ پیاده سازی . اول از همه اینترفیس رو ایجاد میکنیم و یه اسم مناسب براش میزاریم . این اینترفیس داره میگه هر کلاسی از من استفاده کرد باید متد sayWelcome رو پیاده سازی کنه.در واقع ما اینجا استراتژی مشخص میکنیم . interface WelcomeStrategy { function sayWelcome($user); }خب . حالا باید برای هر روشی یک کلاس ایجاد کنیم که از اینترفیس پیروی کنه. برای خوش آمد گویی با ایمیل یک کلاس و برای خوش آمد گویی با پیامک یک کلاس جدا باید بسازیم .اول کلاس خوش آمد گویی با ایمیل را مینویسیم :class WelcomeWithEmail implements WelcomeStrategy { function sayWelcome($user) { // get user email address // use mailer php class // send email to user email address return &quotwelcome with email" } }حالا کلاس خوش آمد گویی با روش ارسال پیامک :class WelcomeWithSMS implements WelcomeStrategy { function sayWelcome($user) { // get user phone number // use sms class //send sms to user phone number return &quotwelcome with sms" } }به دو کلاس فوق توجه کنید . هر دو کلاس قانون را پیاده سازی کردند . در واقع هر دو کلاس دارند متد sayWelcome رو پیاده سازی میکنند ولی هر کلاسی داره به یک روش مخصوص به خودش این کارو میکنه . اولی داره ایمیل ارسال میکنه ولی دومی داره پیامک ارسال میکنه . ولی در هر صورت دارند خوش آمد میگن . ولی هر کدام به یک روش . حالا باید یک کلاس جدید به اسم Welcome بسازیم :require_once 'WelcomeStrategy.php'; class Welcome { private $strategy; public function __construct(WelcomeStrategy $strategy) { $this->strategy = $strategy; } public function say($user) { return $this->strategy->sayWelcome($user); } }به متد سازنده کلاس بالا نگاه کنید . وقتی یک Interface رو به متد سازنده بدیم در واقع داریم به این کلاس میگیم وقتی میخوایم از تو شی جدید بسازیم میتونیم هر کلاسی که این interface رو پیاده سازی میکنه برات ارسال کنیم . در واقع میتونیم هر کلاسی که اینترفیس WelcomeStrategy را implement کرده باشه براش بفرستیم . خب این چه فایده ای داره ؟ دقیقا اینجا میتونیم هر بار که خواستیم یه روش خوش آمد گویی بهش ارسال کنیم و متد sayWelcome اون رو صدا کنیم .خب حالا باید از کلاس Welcome استفاده کنیم . فرض کنید اینجا کاربر لاگین شده و اجرای کد به این فایل رسیده و ما میخایم حالا بهش خوش آمد بگیم . باید کلاس Welcome رو ازش استفاده کنیم (یک شی بسازیم ازش) و بهش بگیم از کدوم روش استفاده کن . در واقع توی حالت زیر بهش گفتیم با پیامک خوش آمد بگو : <?php require_once 'WelcomeWithSMS.php'; $welcome = new Welcome(new WelcomeWithSMS()); $user = new stdClass(); $result = $welcome->say($user); echo $result;در واقع توی این خط :$welcome = new Welcome(new WelcomeWithSMS());داریم استراتژی خودمون رو معلوم میکنیم که میخایم چطوری خوش آمد بگیم . بهش گفتیم از کلاس WelcomeWithSMS استفاده کن و بعد متد say را صدا بزن . کاربر هم براش ارسال میکنیم.$result = $welcome->say($user);ولی اگه بخایم با ایمیل خوش آمد بگیم چی ؟‌ فقط باید شی ساختن از کلاس Welcome رو تغییر بدیم و اینجوری ازش شی بسازیم . در واقع استراتژی را تغیید بدیم .$welcome = new Welcome(new WelcomeWithEmail());به این صورت :<?php require_once 'Welcome.php'; require_once 'WelcomeWithEmail.php'; $welcome = new Welcome(new WelcomeWithEmail()); $user = new stdClass(); $result = $welcome->say($user); echo $result; خب . به این روش میگن دیزاین پترن استراتژی . خیلی خوب و کاربردی هست . یعنی چی ؟فرض کنید یک ماه دیگه ما تصمیم بگیریم که فقط با ارسال نوتیفیشکن به کاربر خوش آمد بگیم.باید چیکار کنیم؟خیلی ساده یک کلاس جدید ایجاد میکنیم با اسم WelcomeWithNotification و از اینترفیس implement میکنیم . و فقط موقع خوش آمد گویی بعد از لاگین کردن کاربر از اون روش استفاده میکنیم .به این شکل :$welcome = new Welcome(new WelcomeWithNotification()); دوستان امیدوارم مفید واقع شده باشه براتون.اگر سوالی بود در خدمتم . تا آموزش بعدی بدرود