دیزاین پترن استراتژی - Strategy Pattern

گردآوری و تالیف : مجله آموزشی راکت
تاریخ انتشار : 09 دی 1396
دسته بندی ها : پی اچ پی

استراتژی پترن درواقع نوعی از دیزاین‌ پترن‌های Behavioral است که به شما اجازه می‌دهد راهکارهایی که برنامهٔ مورد نظرتان باید اجرا کند، بسته به شرایط خاصی که در Runtime (یا هنگام اجرای برنامه) برایش رخ می‌دهد را انتخاب نمایید. شما 2 الگوریتم مختلف را داخل 2 کلاس جدا از یکدیگر به‌اصطلاح Encapsulate می‌کنید و هنگام اجرای برنامه، انتخاب می‌شود که از کدام استراتژی استفاده کند.

فرض کنید مسئولیت ایجاد راه‌حلی برای ادغام 2 کلاس مختلف که 2 عملکرد کاملاً مجزا از یکدیگر دارند را به شما محول کرده‌اند؛ این ۲ کلاس در جاهای مختلفی در سیستم به‌کار رفته‌اند، بنابراین حذف این ۲ کلاس یا تغییر کدهای موجود را باید از سرتان بیرون کنید چرا‌که اصلاً کار ساده‌ای نخواهد بود.

به‌علاوه، با تغییر کد فعلی، شما باید کدهای جدید را دوباره تست کنید چرا که این نوع تغییرات، در سیستمی که به کامپوننت‌های مختلفی وابسته است، در اکثر مواقع باعث ایجاد باگ‌های جدیدی می‌شود. به‌جای این کار، می‌توانید نوعی از استراتژی پترن و آداپتر پترن را پیاده‌سازی نمایید که به‌راحتی می‌توانند این گونه مسائل را حل‌وفصل کنند:

class StrategyAndAdapterExampleClass {
    private $_class_one;
    private $_class_two;
    private $_context;

    public function __construct( $context ) {
            $this->_context = $context;
    }

    public function operation1() {
        if( $this->_context == "context_for_class_one" ) {
            $this->_class_one->operation1_in_class_one_context();
        } else ( $this->_context == "context_for_class_two" ) {
            $this->_class_two->operation1_in_class_two_context();
        }
    }
}

همان‌طور که در کد فوق مشاهده می‌شود، متدی ساخته‌ایم تحت عنوان operation1 که بسته به نوع پارامتر ورودی، نیاز ما را به‌سادگی هندل می‌کند.

در مثال بالا، استراتژیی که مورد استفاده قرار می‌گیرد، طبق متغیر context$ای است که در زمان معرفی کلاس موردنظر ایجاد شده است. اگر شما کلاس اول را مدنظر قرار دهید، این متغییر نیز از class_one استفاده می‌کند و بالعکس.

در چه مواقعی می‌توان از دیزاین پترن Strategy استفاده کنیم؟

فرض کنید شما کلاسی دارید که می‌تواند رکورد کاربر فعلی را آپدیت یا کاربر جدیدی را ایجاد نماید؛ این کلاس در هر ۲ حالت ورودی یکسانی را انتظار دارد از قبیل نام، آدرس، شمارهٔ همراه و غیره اما بسته به موقعیت مورد نظر، باید از فانکشن‌های مختلفی برای به‌روز رسانی یا ایجاد کاربر استفاده کند.

در ساده‌ترین حالت، شما می‌توانید از دستور شرطی if-else استفاده کنید اما اگر خواستید این کلاس را در جای دیگری به کار ببرید، چه‌طور؟ در این مواقع، شما باید همین if-else را در مکان جدید نیز بازنویسی کنید. اما آیا اگر امکان این فراهم شود که فقط نام کلاس را به کار ببرید و بقیه کار را به آن بسپارید راحت‌تر نخواهید بود؟

class User {
    public function CreateOrUpdate($name, $address, $mobile, $userid = null)
    {
        if( is_null($userid) ) {
            // it means the user doesn't exist yet, create a new record
        } else {
            // it means the user already exists, just update based on the given userid
        }
    }
}

استراتژی پترن در حالت عادی شامل کپسوله کردن الگوریتم‌ها در کلاس دیگری می‌شود اما در این مورد، استفاده از کلاس دیگر بی‌فایده است. به خاطر داشته باشید که نیازی نیست همیشه از ساختار پیش‌فرض پیروی کنید. تا‌ وقتی‌ که مفهوم مورد نظر دیزاین پترن رعایت شده و مشکل حل شود، می‌توانید طبق نیازتان دست به تغییر دیزاین پترن مد نظر بزنید.

مقالات پیشنهادی

دیزاین پترن زنجیره - Chain-of-responsibility pattern

در برنامه نویسی به صورت شئ گرا، دیزاین پترنی وجود دارد به نام زنجیره مسئولیت که متشکل از یک مخزن شامل اشیاء فرمان و مجموعه ای از اشیاء پردازش است. هر...

دیزاین پترن Adapter Pattern

آداپتر پترن در اصل یک دیزاین پترن از نوع Structural است که به شما این امکان را می‌دهد تا یک کلاس را با اینترفیس متفاوتی نیز سازگار کنید؛ این کار امکان...

دیزاین پترن الگوی کارخانه - Factory method

در برنامه نویسی شی گرا ، الگوی روش کارخانه یک الگوی خلاقانه است که از روش کارخانه برای حل مسئله ایجاد اشیاء بدون نیاز به تعیین دقیق کلاس شئ که ایجاد م...

دیزاین پترن مقداردهی اولیهٔ تنبل یا کاهلانه - Lazy Initialization

در برنامه نویسی کامپیوتری، مقداردهی اولیهٔ تنبل به انگلیسی ( Lazy Initialization) یک الگو برای به تأخیر انداختن ساخت یک شیء می‌باشد، به طوری که محاسبه...