الگوی دکوریتور (Decorator) توسط گروه ۴ (Gang of four یا GOF) تعریف شده است. الگوی دکوریتور برای اضافه کردن عملکردهای جدید به یک شیئ موجود بدون تغییر ساختار آن استفاده میشود. از این رو الگوی دکوریتور یک راه حل جایگزین برای وراثت یا تغییر رفتار شیئ تلقی میشود. در این مقاله من میخواهم روش کار با الگوی دکوریتور را آموزش دهم.
الگوی دکوریتور چیست؟
الگوی دکوریتور برای اضافه کردن عملکردهای جدید به یک شیئ موجود بدون تغییر ساختار آن استفاده میشود. این الگو یک کلاس decorator میسازد که کلاس اصلی را در بر میگیرد و رفتار یا عملیات یک شیئ را در هنگام اجرا تغییر میدهد.
الگوی دکوریتور – دیاگرام UML و پیاده سازی
کلاس دیاگرام UML برای پیاده سازی الگوی طراحی دکوریتور در زیر آورده شده است:
کلاسها، اینترفیسها و اشیاء در نمودار UML بالا به شرح زیر است:
۱- Component
یک اینترفیس که اعضائی که با ConcreteClass و Decorator پیادهسازی خواهند شد را شامل میشود.
۲- ConcreteComponent
کلاسی است که اینترفیس Component را پیاده سازی میکند.
۳- Decorator
یک کلاس تجریدی است که اینترفیس Component را پیاده سازی میکند و شامل یک رفرنس به نمونه Component است. این کلاس همچنین به عنوان کلاس پایه جهت همه دکوریتورها برای کامپوننتها عمل میکند.
۴- ConcreteDecorator
این کلاس از کلاس Decorator به ارث برده شده و دکوریتور را برای کامپوننتها فراهم میکند.
پیاده سازی C#
public interface Component { void Operation(); } public class ConcreteComponent : Component { public void Operation() { Console.WriteLine("Component Operation"); } } public abstract class Decorator : Component { private Component _component; public Decorator(Component component) { _component = component; } public virtual void Operation() { _component.Operation(); } } public class ConcreteDecorator : Decorator { public ConcreteDecorator(Component component) : base(component) { } public override void Operation() { base.Operation(); Console.WriteLine("Override Decorator Operation"); } }
الکوی دکوریتور – مثال
نقش ها:
کلاسها، اشیاء و اینترفیس ها در نمودار کلاس بالا میتواند به شرح زیر تعریف شود:
- Vehicle – Component Interface.
- HondaCity– ConcreteComponent class.
- VehicleDecorator– Decorator Class.
- Special Offer– ConcreteDecorator class.
مثال C#:
/// <summary> /// The 'Component' interface /// </summary> public interface Vehicle { string Make { get; } string Model { get; } double Price { get; } } /// <summary> /// The 'ConcreteComponent' class /// </summary> public class HondaCity : Vehicle { public string Make { get { return "HondaCity"; } } public string Model { get { return "CNG"; } } public double Price { get { return 1000000; } } } /// <summary> /// The 'Decorator' abstract class /// </summary> public abstract class VehicleDecorator : Vehicle { private Vehicle _vehicle; public VehicleDecorator(Vehicle vehicle) { _vehicle = vehicle; } public string Make { get { return _vehicle.Make; } } public string Model { get { return _vehicle.Model; } } public double Price { get { return _vehicle.Price; } } } /// <summary> /// The 'ConcreteDecorator' class /// </summary> public class SpecialOffer : VehicleDecorator { public SpecialOffer(Vehicle vehicle) : base(vehicle) { } public int DiscountPercentage { get; set; } public string Offer { get; set; } public double Price { get { double price = base.Price; int percentage = 100 - DiscountPercentage; return Math.Round((price * percentage) / 100, 2); } } } /// <summary> /// Decorator Pattern Demo /// </summary> class Program { static void Main(string[] args) { // Basic vehicle HondaCity car = new HondaCity(); Console.WriteLine("Honda City base price are : {0}", car.Price); // Special offer SpecialOffer offer = new SpecialOffer(car); offer.DiscountPercentage = 25; offer.Offer = "25 % discount"; Console.WriteLine("{1} @ Diwali Special Offer and price are : {0} ", offer.Price, offer.Offer); Console.ReadKey(); } }
الکوی دکوریتور – خروجی
چه زمانی از این الگو استفاده کنیم؟
- اضافه نمودن وضعیت یا رفتار به یک شیئ به صورت داینامیک
- ایجاد تغییر در بعضی از اشیاء در یک کلاس بدون تأثیر بر سایرین
شما چه فکر میکنید؟
من امیدوارم که شما از الگوی دکوریتور هنگام طراحی نرمافزارتان لذت ببرید. منتظر نظرات و پیشنهادات شما هستم.
منبع: http://www.dotnettricks.com/learn/designpatterns/decorator-design-pattern-dotnet
ثبت ديدگاه