معرفی الگوی طراحی Decorator

معرفی الگوی طراحی Decorator

مدت مطالعه : 3 دقیقه

06 اردیبهشت 1402

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

الگوی طراحی Decorator یک الگوی طراحی ساختاری(structural) است که به شما امکان می دهد به صورت پویا رفتاری را به یک شی در زمان اجرا اضافه کنید. این الگو می تواند رفتار اضافی به یک کلاس اضافه کند یا رفتار موجود را بدون تغییر شی اصلی تغییر دهد.

در الگوی Decorator چندین عنصر کلیدی وجود دارد:

  • Component: یک کلاس واسط یا انتزاعی است که متدهای رایج را برای Concrete Component و Decorator تعریف می کند. 
  • Concrete Component: یک کلاس است که رابط Component را پیاده سازی می کند و عملکرد اصلی شیئی را که می توان تغییر داد را ارائه می دهد.
  • Decorator: یک کلاس انتزاعی است که رابط Component را پیاده سازی می کند و یک ارجاع به شی Component را نگهداری می کند. Decorator با فراخوانی متدهای شی اصلی و اضافه کردن برخی پردازش های اضافی قبل یا بعد از متد اصلی، رفتار اضافی را به شی اضافه می کند.
  • Concrete Decorator: کلاسی است که Decorator را پیاده‌سازی می‌کند و قابلیت های جدیدی را به شی اضافه می کند.
decorator

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

 

در ادامه یک مثال ساده از الگوی Decorator در سی شارپ آورده شده است:

// Component interface
public interface IPizza
{
    string GetDescription();
    double GetCost();
}
// Concrete Component class
public class PlainPizza : IPizza
{
    public string GetDescription()
    {
        return "Thin dough";
    }
    public double GetCost()
    {
        return 4.00;
    }
}
// Decorator abstract class
public abstract class ToppingDecorator : IPizza
{
    protected IPizza _pizza;
    public ToppingDecorator(IPizza pizza)
    {
        _pizza = pizza;
    }
    public virtual string GetDescription()
    {
        return _pizza.GetDescription();
    }
    public virtual double GetCost()
    {
        return _pizza.GetCost();
    }
}
// Concrete Decorator classes
public class TomatoSauce : ToppingDecorator
{
    public TomatoSauce(IPizza pizza) : base(pizza) { }
    public override string GetDescription()
    {
        return _pizza.GetDescription() + ", tomato sauce";
    }
    public override double GetCost()
    {
        return _pizza.GetCost() + 0.35;
    }
}
public class Mozzarella : ToppingDecorator
{
    public Mozzarella(IPizza pizza) : base(pizza) { }
    public override string GetDescription()
    {
        return _pizza.GetDescription() + ", mozzarella";
    }
    public override double GetCost()
    {
        return _pizza.GetCost() + 0.50;
    }
}
// Client code
class Program
{
    static void Main(string[] args)
    {
        // Create a plain pizza
        IPizza basicPizza = new PlainPizza();
        // Add tomato sauce and mozzarella
        IPizza pizzaWithSauceAndCheese = new TomatoSauce(new Mozzarella(basicPizza));
       Console.WriteLine($"Description: {pizzaWithSauceAndCheese.GetDescription()}");
       Console.WriteLine($"Cost: {pizzaWithSauceAndCheese.GetCost():C}");
    }
}

در این مثال، رابط IPizza را داریم که متدهای GetDescription و GetCost را تعریف می کند. ما همچنین کلاس PlainPizza را داریم که رابط IPizza را پیاده سازی می کند.

کلاس انتزاعی ToppingDecorator رابط IPizza را پیاده سازی می کند و شیئی از نوع IPizza را نگهداری می کند. کلاس های Concrete Decorator مانند TomatoSauce و Mozzarella کلاس ToppingDecorator را پیاده سازی می‌کنند و رفتار خود را اضافه می کنند.

در نهایت در کد کلاینت یک نمونه PlainPizza ایجاد می کنیم و آن را با TomatoSauce و Mozzarella  تغییر می‌دهیم.

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

design patterns

ایجاد کننده (Creational):الگوی طراحی Factory 
الگوی طراحی Builder 
الگوی طراحی Singleton 
الگوی طراحی Prototype 
الگوی طراحی Abstract Factory 
ساختاری (Structural):الگوی طراحی Adapter 
الگوی طراحی Bridge 
الگوی طراحی Composite 
الگوی طراحی Decorator 
الگوی طراحی Facade 
الگوی طراحی Flyweight 
الگوی طراحی Proxy 
رفتاری (Behavioral):الگوی طراحی Chain of Responsibility 
الگوی طراحی Command 
الگوی طراحی Interpreter 
الگوی طراحی Mediator 
الگوی طراحی Memento 
الگوی طراحی Observer 
الگوی طراحی State 
الگوی طراحی Strategy 
الگوی طراحی Template Method 
الگوی طراحی Visitor 
الگوی طراحی Iterator 
  • اشتراک گذاری:
محمدرضا باباخانی
محمدرضا باباخانی

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

آخرین مطالب

سرویس مش؛ ساده سازی ارتباطات میکروسرویس و افزایش رؤیت پذیری

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

اهمیت محاسبات لبه یا Edge Computing

ا توجه به سرعت تحول فناوری، یکی از مفاهیمی که توجه زیادی را به خود جلب کرده و نحوه تعامل ما با سیستم های دیجیتال را تغییر می دهد، محاسبات لبه (Edge Computing) است.

معماری رویداد محور چیست؟

معماری رویداد محور (EDA) یک الگوی طراحی نرم افزار است که در توسعه نرم افزار های مدرن به طور چشمگیری محبوب شده است. در این معماری، جریان داده ها با وقوع رویدادها تعیین می شود. بر خلاف سیستم های متمرکز سنتی که دائماً در حال بررسی وضعیت جدید هستند. معماری رویداد محور به ویژه برای سیستم هایی مفید است که به پردازش حجم زیادی از داده ها بصورت بلادرنگ(real-time) نیاز دارند.

ثبت دیدگاه