استارت‌آپ و کارآفرینی

دیزاین پترن ها: فساد پترن (The Facade Pattern)

مثل همیشه وقتی صحبت از دیزاین پترن میشه , سوالهایی که پیش میاد :

چرا ما باید از دیزاین پترن ها تو برنامه نویسی استفاده کنیم ؟

کد ما بدون استفاده از اون هم داره خوب کار میکنه .

در جوابی که من همیشه میگم , “آیا شما ترجیح میدید توی خونه لوکس زندگی کنید یا توی خونه ساده با چهارتا دیوار ؟” ,  هر دوتاشون دارند یه هدفی رو دنبال می‌کنند .

اصولا, ما به دنبال خونه لوکس هستیم چون همیشه امکانات بهتری رو میده و همیشه نیاز به نگه داری و تعمیر کمتری داره . نگه داری و تعمیراتش هم بدون دردسر میشه چون زیربناش خیلی خوب زده شده.

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

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

  • creational patterns
  • structural patterns
  • behavioral patterns
  • concurrency patterns پترن همروندی

تو این مطلب در مورد دیزاین پترن فساد (The Facade Pattern) حرف میزنیم که از شاخه ی پترن‌های ساختاری هست چون با این که کدتون ساختارش چی باشه که به راحتی قابل فهم و قابل نگه داری باشه کار داره. با جوانب مثبت و منفیش و با فاکتورهایی که نشون میده ما کی باید ازش استفاده کنیم آشنا میشید. زبان PHP رو پایه کار قرار میدیم و مثال‌هایی که زده میشه با این زبان هست. ولی در هر صورت مفاهیم برای همه زبان‌ها یکی هست و فقط کافیه syntax رو برای زبان خودتون تغییرش بدید .

 دیزاین پترن فساد

UML دیزاین پترن

facade_design_pattern
مشکل
فرض کنید می‌خواید یه سری عملیات رو پشت سر هم انجام بدین و این عملیات تو کدمون تو جاهای مختلف استفاده میشه، شما مجبورید همه اون کدها رو بارها و بارها تو جاهای مختلف کپی کنید. این کار رو انجام میدید ولی بعد از چند روز نیاز دارید یکمی از اون کد رو تغییر بدید .

مشکل رو فهمیدین؟ شما مجبورید همه جاها اون کد رو تغییر بدین، سخته، نه ؟

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

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

تو این حالت شما به جای اینکه همه کارهارو خودتون انجام بدید، باید از یه برنامه ریز عروسی استفاده کنید و مطمئن باشید که همه چیز به صورت خوب مدیریت شده و با حداقل ترین احتمال خطا انجام بشه.

اینجا، شما به عنوان مشتری (client) هستید که کار رو آغاز کرده و برنامه ریز عروسی یه عنوان فساد (facade) عمل میکنه و کاری رو که شما برنامه ریزی کردید رو تا کامل شدنش انجام میده.

مثال کدی

تو این بخش یه مثال دیگه که تو خیلی از وبسایت‌ها مشترکه رو می‌بینیم . البته این بار با کد. ما پیاده سازی دیزاین پترن فساد رو برای پروسه خرید محصول رو بررسی می‌کنیم. ولی قبل اینکه یه کد کامل رو با دیزاین پترن فساد ببینیم بیاین یه کد که مشکل داره رو ببینیم.

یه فرآیند ساده خرید شامل بخش‌های زیر هست :

  1. افزودن محصول به سبد خرید
  2. محاسبه مبلغ قابل پرداخت
  3. محاسبه تخفیف
  4. آماده سازی درخواست

مشکل

// Simple CheckOut Process
$productID = $_GET['productId'];
 
$qtyCheck = new productQty();
 
if($qtyCheck->checkQty($productID) > 0) {
     
    // Add Product to Cart
    $addToCart = new addToCart($productID);
     
    // Calculate Shipping Charge
    $shipping = new shippingCharge();
    $shipping->updateCharge();
     
    // Calculate Discount Based on
    $discount = new discount();
    $discount->applyDiscount();
     
    $order = new order();
    $order->generateOrder();
}

تو کد بالا می بینید که برای کامل شدن یه فرآیند خرید نیاز هست تا از شی های مختلف با متدهای متفاوتی استفاده کنیم. حالا فرض کنید همین کد رو تو بخش‌های مختلف استفاده کردید و نیاز دارید یه تغییر کوچیک تو فرآیند بدید. خب بهترین حالت اینه که همه کدهارو تو یه جا داشته باشیم که در صورت نیاز به تغییر فقط همون جارو تغییر بدیم.

 راه حل
ما همون کد رو اینبار با فساد پترن می‌نویسیم که باعث میشه کد قابل نگه داری و گسترش پذیری بیشتری بشه .

class productOrderFacade {
         
    public $productID = '';
     
    public function __construct($pID) {
        $this->productID = $pID;
    }
     
    public function generateOrder() {
         
        if($this->qtyCheck()) {
             
            // Add Product to Cart
            $this->addToCart();
             
            // Calculate Shipping Charge
            $this->calulateShipping();
             
            // Calculate Discount if any
            $this->applyDiscount();
             
            // Place and confirm Order
            $this->placeOrder();
             
        }
         
    }
     
    private function addToCart () {
        /* .. add product to cart ..  */
    }
     
    private function qtyCheck() {
         
        $qty = 'get product quantity from database';
         
        if($qty > 0) {
            return true;
        } else {
            return true;
        }
    }
     
     
    private function calulateShipping() {
        $shipping = new shippingCharge();
        $shipping->calculateCharge();
    }
     
    private function applyDiscount() {
        $discount = new discount();
        $discount->applyDiscount();
    }
     
    private function placeOrder() {
        $order = new order();
        $order->generateOrder();
    }
}

حالا ما فساد درخواست محصولمون رو داریم. تنها کاری که باید بکنیم اینه با یه تیکه کد ارتباط با اون کلاس فسادمون رو برقرار کنیم به جای اینکه اون همه کد قبلی رو بزنیم.

کد زیر رو نیگاه کنید.

// Note: We should not use direct get values for Database queries to prevent SQL injection
$productID = $_GET['productId'];
 
// Just 2 lines of code in all places, instead of a lengthy process everywhere
$order = new productOrderFacade($productID);
$order->generateOrder();

حالا فرض کنید می‌خواید یه تغییراتی تو پروسه خرید بدید. کافیه کلاس فسادمون رو فقط تغییر بدیم.

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

توی لاراول از این دیزاین پترن استفاده زیادی شده که توی مطالب بعدی سعی می‌کنم فساد رو تو لاراول توضیح بدم براتون.

هر سوالی یا نظری دارید برامون بنویسید . البته این مطلب ترجمه این لینک هست و اگه مشکلی توی ترجمه دیدید می‌تونید به اون مراجعه کنید و به من هم بگید، که رفعش کنم ممنون میشم.

5 نظرات
  1. علی می گوید

    ممنون امیر جان
    عالی بود.

  2. محمدجعفر می گوید

    متوجه نمی‌شم فرقش با یه برنامه‌ی ماژولار چیه؟
    برای جلوگیری از تکرار کد تابع می‌سازیم. Facade چه چیزی اضافه تر از ساخت تابع داره؟

  3. دریا می گوید

    منم سئوال دوستمونو دارم.خوب وقتی ۳لایه هم کار میکردیم.یه بار متد را تعریف میکردیم در لایه ui کال میکردیم چه ضرورتی به استفاده از facade هست

  4. Y.P.Y می گوید

    الگوی Facade عمل ساده/خلاصه سازی(simplify) کلاس رو انجام میده
    درغیراینصورت هر الگویی هست بجز Facade

  5. faryar می گوید

    ممنون از وقتی که گذاشتید لطفا به شاخه دیزاین پترن ها توجه ویژه داشته باشید // ممنون

ارسال یک پاسخ

آدرس ایمیل شما منتشر نخواهد شد.