آموزش Facade Design Pattern

Image تحقیقات

آموزش Facade Design Pattern

سلام دوستان عزیز

بعد از یه وقفه ای که داشتم دوباره امروز اومدم تا درباره  دیزاین پترن فساد صحبت کنیم.

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

در واقع کلاس فساد ، کلاس های مختلی (زیر سیستم یا sub class) رو به مدیریت میکنه  و به جای اینکه برنامه نویس در نهایت با همه ی ساب کلاس ها در ارتباط باشه و گیج بشه… تنها با کلاس فساد در ارتباط است و اطلاعات لازم رو به این کلاس میده و خود کلاس کارهای مربوطه رو به ترتیب انجام میده.

 

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

عکس بالا رو مشاهده کنید..کلاس بالایی  همان facade  ما هست  و داره ساب کلاس ها یا ساب سیستم ها رو کنترل میکنه.

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

برای این کار در حالت معمولی 3 تا کلاس داریم به نام های  Rectangle و Square و Circle. که کدهای لازم برای رسم  مستطیل و مربع و دایره را درون هر کدام از این کلاس ها در متدی به نام draw نوشتیم.. (فرض می کنیم کدهاری رسم شکل نوشته شده است.)

کلاس Rectangle

<?php

class Rectangle implements Shape {

    public function draw($height , $width){
//        Draw Rectangle
        echo "Draw Rectangle $height * $width  ...". '
';
    }

}

 

و حالا کلاس Square

<?php

class Square implements Shape {
    public function draw($height , $width){
//        Draw Square
        echo "Draw Square ... $height * $width". '
';
    }
}

و کلاس Circle

<?php

class Square implements Shape {
    public function draw($height , $width){
//        Draw Square
        echo "Draw Square ... $height * $width". '
';
    }
}

یک Interface هم داریم که این 3 تا کلاس ازش Implements گرفتن .

<?php

interface Shape {

    public function draw($height , $width);
}

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

مانند زیر :

<?php

include 'Shape.php';
include 'Rectangle.php';
include 'Square.php';
include 'Circle.php';

$rectangle=new Rectangle();
$square=new Square();
$circle=new Circle();

$rectangle->draw('10','10');
$circle->draw('10','10');
$circle->draw('10','10');

 

خروجی کد بالا :

Draw Rectangle 10 * 10 ...
Draw Circle ... 10 * 10
Draw Circle ... 10 * 10

فکر کنید اگر جاهای دیگه ای از پروژه هم بخوایم  به این صورت کار کنیم و هر بار تمام کدهایی که در فایل Index.php نوشتیم در صفحات دیگری هم بنوسیم چقد مسخره میشه کار… تازه این مثال ما خیلی ساده است در پروژه ها کلاس ها پیچیده تر هستند.

برای حل این مشکل صدا زدن بیخودی و تکراری کدها  ، می توانید از فساد اسفتاده کنیم.

برای استفاده از پترن فساد میام یک کلاس دیگه به پروژه اضافه میکنیم مثلا به FacadeClass.

<?php
include 'Shape.php';
include 'Rectangle.php';
include 'Square.php';
include 'Circle.php';

class FacadeClass {

    protected  static $height;
    protected  static $width;


    public static function drawShapes($height, $width)
    {
        self::$height=$height;
        self::$width=$width;

        self::drawRectangle(self::$height, self::$width);
        self::drawSquare(self::$height, self::$width);
        self::drawCircle(self::$height, self::$width);

    }

    private function drawRectangle($height,$width)
    {
        $rectangle=new Rectangle();
        $rectangle->draw($height, $width);
    }
    private function drawSquare($height,$width)
    {
        $rectangle=new Square();
        $rectangle->draw($height, $width);
    }
    private function drawCircle($height,$width)
    {
        $rectangle=new Circle();
        $rectangle->draw($height, $width);
    }


}

 

و برای استفاده از این کلاس کافیه فایل Index.php رو به صورت زیر تغییر بدیم :

<?php

include 'FacadeClass.php';

FacadeClass::drawShapes('10','10');
FacadeClass::drawShapes('20' ,'20');

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

خروجی تغییرات بالا هم مانند قبلی خواهد بود :

Draw Rectangle 10 * 10 ...
Draw Square ... 10 * 10
Draw Circle ... 10 * 10
Draw Rectangle 20 * 20 ...
Draw Square ... 20 * 20
Draw Circle ... 20 * 20

بچه ها این نمونه کد رو هم قرار میدم اینجا… بعد از اینکه مطالب بالا رو خوندین این مثال رو هم چک کنید.

/**
 * Ok so this looks pretty terrible, right? Everything is public and crappy method names!
 */
interface SendMailInterface
{
    public function setSendToEmailAddress($emailAddress);
    public function setSubjectName($subject);
    public function setTheEmailContents($body);
    public function setTheHeaders($headers);
    public function getTheHeaders();
    public function getTheHeadersText();
    public function sendTheEmailNow();
}

/**
 * Implementing that crappy interface
 */
class SendMail implements SendMailInterface
{
    public $to, $subject, $body;
    public $headers = array();

    public function setSendToEmailAddress($emailAddress)
    {
        $this->to = $emailAddress;
    }
    
    public function setSubjectName($subject)
    {
        $this->subject = $subject;
    }

    public function setTheEmailContents($body)
    {
        $this->body = $body;
    }

    public function setTheHeaders($headers)
    {
        $this->headers = $headers;
    }

    public function getTheHeaders()
    {
        return $this->headers;
    }

    public function getTheHeadersText()
    {
        $headers = "";
        foreach ($this->getTheHeaders() as $header) {
            $headers .= $header . "\r\n";
        }
    }

    public function sendTheEmailNow()
    {
        mail($this->to, $this->subject, $this->body, $this->getTheHeadersText());
    }
}

/**
 * A facade wrapper around the crappy SendMail, to improve method names.
 */
class SendMailFacade
{
    private $sendMail;

    public function __construct(SendMailInterface $sendMail)
    {
        $this->sendMail = $sendMail;
    }

    public function setTo($to)
    {
        $this->sendMail->setSendToEmailAddress($to);
        return $this;
    }
    
    public function setSubject($subject)
    {
        $this->sendMail->setSubjectName($subject);
        return $this;
    }

    public function setBody($body)
    {
        $this->sendMail->setTheEmailContents($body);
        return $this;
    }

    public function setHeaders($headers)
    {
        $this->sendMail->setTheHeaders($headers);
        return $this;
    }

    public function send()
    {
        $this->sendMail->sendTheEmailNow();
    }
}

$to      = "bob@marley.com";
$subject = "Bob Marley and the Wailers";
$body    = "Bob Marley and the Wailers were a Jamaican reggae band created by Bob Marley, Peter Tosh and Bunny Wailer.";
$headers = array(
    "From: Steve@Irwin.com"
);

// Using the minging SendMail class
$sendMail = new SendMail();
$sendMail->setSendToEmailAddress($to);
$sendMail->setSubjectName($subject);
$sendMail->setTheEmailContents($body);
$sendMail->setTheHeaders($headers);
$sendMail->sendTheEmailNow();

// Using the sexy SendMailFacade class
$sendMail       = new SendMail();
$sendMailFacade = new sendMailFacade($sendMail);
$sendMailFacade->setTo($to)->setSubject($subject)->setBody($body)->setHeaders($headers)->send();

 

امیدوارم با این دیزارن پترن هم آشنا شده باشین  و کمکی کرده باشه بهتون.