قبلا در رابطه با اینکه دیزاین پترن یا الگوی طراحی چیست؟ صحبت کردیم. در این مقاله در رابطه با استراتژی پترن صحبت میکنیم.
تصور کنید که میخواهیم از شهر تهران به شیراز سفر کنیم برای اینکار ما میتوانیم از روشهای مختلفی همچون سفر با قطار، هواپیما، اتوبوس، خودروی سواری، دوچرخه و یا پیاده استفاده کنیم. اینکه ما در چه شرایطی هستیم، چقدر پول داریم، چقدر زمان داریم، وضعیت هوا چطور است و در کل شرایطی که داریم چگونه است مشخص میکند که از کدام روش سفر کنیم. انتخاب هر روش استراتژی ما برای سفر بر اساس شرایط موجود است.
ما همین الگو را در دنیای برنامه نویسی به اسم استراتژی پترن داریم که بر اساس شرایط به وجود آمده در هنگام اجرای نرم افزار یک الگوریتم اجرا میشود. حالا به بررسی دقیقتر این الگو میپردازیم.
Strategy Pattern یکی از الگوهای Behavioral (رفتاری) است که ما هنگام توسعه نرم افزار بر اساس موقعیت و شرایط مشخص میکنیم از چه استراتژی یا الگوریتمی استفاده کنیم.
Strategy Pattern این امکان را میدهد تا اجرای الگوریتمها بر اساس موقعیت و شرایط متفاوت تغییر کنند. در این الگو تعدادی از الگوریتمها را تعریف میکنیم و هر یک را در کلاسی جداگانه و مستقل قرار میدهیم تا قابل انتخاب باشند.
الگوی strategy قابلیت انتخاب یک الگوریتم در زمان اجرا را ممکن میسازد.
در واقع این الگو:
وقتی که ما برای اجرای یک کار مشخص روشهای مختلفی داریم بهترین الگو برای اجرای آن رفتار استراتژی پترن است، برای مثال وقتی ما میخواهیم یک درگاه بانک را پیاده سازی کنیم برای پرداخت مبلغ توسط کابر روشهای مختلفی وجود دارد برای نمونه: پرداخت انلاین، پرداخت در محل، حواله مبلغ به صورت کارت به کارت یا واریز به حساب انتخاب هر کدام از روشها توسط کاربر صورت میگیرد و در این حالت شرایط وبسایت و نرم افزار تعیین میکند که کاربر کدام روش پرداخت را انتخاب کند مثلا وبسایت ما قابل اعتماد باشد، همه روشها در نرم افزار در دسترس باشد.
حالا وقتی کاربر پرداخت انلاین را انتخاب کند، پرداخت انلاین Providerهای مختلفی دارد و باز در این قسمت نیز ما این الگو را داریم چونکه هر provider به یک نحو امکان پرداخت انلاین را در اختیار ما قرار میدهد مثلا API پرداخت بانک ملت و بانک سامان و ... باهم تفاوت دارد و از طرفی کاربر خودش پرداخت از کدام بانک را انتخاب میکند.
ابتدا یک قرارداد برای تمام کلاسها ایجاد میکنیم که همه کلاسهایی که داریم از آن قرارداد باید پیروی کنند.
interface PaymentProviderContract { public function initialize(); public function purchase(array $data); }
در قدم بعدی ما تمام کلاسهایی که داریم را طبق ساختار زیر پیاده سازی میکنیم.
class ProviderName implements PaymentProviderContract { public function __construct() { // ... } public function initialize() { /// ... /// return $gateway; } public function purchase(array $data) { /// return $response } }
و در قدم آخر هم ما میتوانیم داخل کنترلری که پرداخت را پیاده سازی کرده ایم به صورت زیر فراخوانی کنیم.
$this->PaymentProvider = "Payment\\Providers\\{$provider}" $provider = new $this->PaymentProvider; return $provider->purchase($data);