الگوهای طراحی راه حل های اثبات شده ای برای مشکلات طراحی نرمافزار هستند. آنها به بهبود کیفیت کد، ارتقای قابلیت استفاده مجدد و افزایش قابلیت نگهداری کمک می کنند. ما از آنها برای صرفهجویی در زمان و تولید کد های با کیفیت، توسعهپذیر و انعطافپذیر استفاده میکنیم. در این مطلب قصد داریم الگوی طراحی Decorator را معرفی کنیم.
الگوی طراحی Decorator یک الگوی طراحی ساختاری(structural) است که به شما امکان می دهد به صورت پویا رفتاری را به یک شی در زمان اجرا اضافه کنید. این الگو می تواند رفتار اضافی به یک کلاس اضافه کند یا رفتار موجود را بدون تغییر شی اصلی تغییر دهد.
در الگوی 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 تغییر میدهیم.
برای مطالعه سایر الگو های طراحی، میتوانید از لیست زیر استفاده کنید. همچنین یک مخزن کد در گیت هاب که شامل همهی الگو های طراحی میشود، برای شما قرار گرفته است.
من محمدرضا باباخانی هستم، توسعه دهنده نرم افزار. در اینجا تجربیات، نظرات و پیشنهادات خودم رو درباره تکنولوژی مینویسم. امیدوارم مطالبی که مینویسم بدردتون بخوره.
ثبت دیدگاه