آموزش Decorator Design Pattern
- توسط : علی حسین شهابی
- 0 نظر
سلام بر همه دوستاان
امروز میریم سراغ معرفی یه دیزاین پترن دیگه به نام Decorator.
هدف الگوی Decorator
هدف از پیاده سازی الگوی Decorator اضافه کردن یک وضعیت و یا یک رفتار (Behavior) به یک کلاس بدون تغییر دادن آن می باشد. این عمل می تواند کاملا به صورت داینامیک انجام شود. این دو مشخصه (تغییر نکردن کلاس فعلی و داینامیک بودن)، Decorator را تبدیل به یکی از پرکاربردترین الگوهای طراحی شیء گرا کرده است.
طرح مساله و مثال ساده
با یک مثال بسیار ساده به سراغ مشکل و سپس راه حل آن می رویم. کلاس های زیر را در نظر بگیرید :
<?php
interface Icomponent
{
public function getInfo();
}
یک اینترفیس به نام IComponent که توسط کلاس Component پیاده سازی شده است و متن ساده ای را برمی گرداند. متن برگردانده شده نیز بر روی صفحه چاپ می شود :
اکنون فرض کنید نیاز دارید این متن ساده را (که شامل حروف کوچک و بزرگ است) تماما به حروف بزرگ تبدیل کنید و برگردانید.
از آنجا که (فرضا) کلاس Component در قست های دیگری از برنامه نیز استفاده شده است، تغییر آن برای شما مشکل بوده و یا مقدور نیست. اما چگونه می توانید رفتار جدید را بدون تغییر کلاس فعلی به آن اضافه کنید؟ یکی از راه حل هایی که شاید به ذهنتان رسیده، ارث بری از کلاس Component و Override کردن متد GetInfo باشد. اما ارث بری راه حلی تنها محدود به کلاس Component خواهد شد. برای مثال در صورتی که پیاده سازی دیگری از کلاس IComponent انجام شود، باز با مشکل فوق مواجه خواهیم شد. همچنین ارث بری در زمان اجرا (Runtime) قابل تغییر نبوده و محدود می باشد. از آن سو در صورتی که کلاس Component به صورت Sealed تعریف شده باشد، امکان ارث بری وجود ندارد.
راه حل Decorator
نکته ی اصلی و کلیدی در پیاده سازی الگوی Decorator ارث بری از Interface اصلی و همچنین داشتن یک نمونه از آن در کلاس Decorator به صورت همزمان می باشد. به کد زیر دقت کنید :
<?php
class ComponentUppercaseDecorator implements Icomponent
{
public $component;
function __construct(Icomponent $component)
{
$this->component = $component;
}
public function getInfo()
{
echo strtoupper($this->component->getInfo());
}
}
کلاسی با نام ComponentUppercaseDecorator تعریف شده است که هم IComponent را پیاده سازی کرده و هم شامل یک نمونه از آن می شود. سپس در پیاده سازی متد GetInfo از آن نمونه برای گرفتن متن استفاده کرده، و پس از Uppercase کردن آن، مقدار برگردانده می شود. همانطور که ملاحظه میکنید کلاس Component کوچکترین تغییری نمیکند. حال در صفحه Index.php از کلاس نوشته شده استفاده میکنیم :
<?php
include 'Component.php';
include 'ComponentUppercaseDecorator.php';
$component=new Component();
// به صورت عادی چاپ می کند
echo $component->getInfo();
echo '<br>';
$decoratorComponent=new ComponentUppercaseDecorator($component);
// به صورت حروف بزرگ چاپ می کند
$decoratorComponent->getInfo();
حال با اجرای برنامه مشاهده خواهید کرد که متن به صورت معمولی و Uppercase بر چاپ خواهد شد.
خروجی :
ali HoSSein shAhabi
ALI HOSSEIN SHAHABI