الگوهای طراحی - الگوی Strategy

شنبه 13 دی 1399

الگوی Strategy تحت الگوهای ساختاری می باشد. اهدافی که الگوی Strategy آن ها را دنبال می کند عبارتند از: 1. پیاده سازی الگوریتم های مختلف 2. عدم وابستگی استفاده کننده به پیاده سازی 3. تاکید بر تک وظیفه ای 4. رعایت اصل OCP به زبان ساده در الگوی Strategy قسمت متغیر کلاس را جدا و قسمت ثابت کلاس را هم جدا پیاده سازی می کنیم. از مثال های پرکاربرد می توانیم سیستم تخفیف در فروشگاه را نام ببریم.

الگوهای طراحی - الگوی Strategy

از نشانه های استفاده نکردن Strategy در کدهای خود، روبرو شدن با switch case و یا if و else های طولانی می باشد.

در این مثال یک کلاس مشتری داریم که مشتری ها می توانند تایپ های متفاوت داشته باشند بنابراین:

public enum CustomerType
{
            Gold,
            Bronze,
            Silver,
}
public class Customer
{
            public string FirstName { get; set; }
            public string LastName { get; set; }
            public CustomerType Type { get; set; }
}

و همچنین یک کلاس به نام Order ایجاد می کنیم که با توجه به نوع مشتری، قیمت نهایی را برمی گرداند:

public class Order
{
            public Order(int price, Customer customer)
            {
                Price = price;
                Customer = customer;
            }
            public int Price { get; set; }
            public Customer Customer { get; set; }
            public int GetFinalPrice()
            {
                switch (Customer.Type)
                {
                    case CustomerType.Gold:
                        return (Price - (Price * 20 / 100));
                    case CustomerType.Bronze:
                        return (Price - (Price * 10 / 100));
                    case CustomerType.Silver:
                        return (Price - (Price * 5 / 100));
                    default:
                        return (Price);
                }
            }
}

حالا من یک نوع جدید به enum خودم اضافه می کنم. اتفاقی که می افتد در متد GetFinalPrice کلاس Order باید نوع جدید رو هم اضافه کنم و این یعنی تغییر در کلاس و زیر سوال بردن اصل open closed principle.

بنابراین راه حل، جدا کردن قسمت ثابت و متغیر کلاس می باشد. در اینجا قسمت متغیر، محاسبه قیمت نهایی است.

یک abstract class و implementation های متفاوت برای محاسبه تخفیف ایجاد می کنم.

public abstract class CalcFinalPrice
{
            public abstract int Calculate(int price);
}
public class GoldCalculator : CalcFinalPrice
{
            public override int Calculate(int price)
            {
                return (price - (price * 20 / 100));
            }
}
public class SilverCalculator : CalcFinalPrice
{
            public override int Calculate(int price)
            {
                return (price - (price * 5 / 100));
            }
}

و به کلاس Order به جای Customer، کلاس CalcFinalPrice را جهت محاسبه تخفیف ارسال می کنم.

public class Order
{
            private readonly CalcFinalPrice _calcFinalPrice;
            public Order(int price, CalcFinalPrice calcFinalPrice)
            {
                Price = price;
                _calcFinalPrice = calcFinalPrice;
            }
            public int Price { get; set; }
            public int GetFinalPrice()
            {
                return (_calcFinalPrice.Calculate(Price));
            }
}

حالا با اضافه شدن یک نوع جدید فقط یک کلاس جدید ایجاد می کنیم و کلاس ما تغییری نمی کند.

نکته ای که هست، اگر تایپ مشتری اضافه شود ولی استراتژی تخفیف برای آن دیده نشود سیستم ما خطا می دهد. راه حل این است که یک کلاس Null Object ایجاد کنیم.

public class NullCalculator : CalcFinalPrice
{
            public override int Calculate(int price)
            {
                return (price);
            }
}

پایان

محسن فرخی

نویسنده 2 مقاله در برنامه نویسان
  • C#.net
  • 1k بازدید
  • 1 تشکر

کاربرانی که از نویسنده این مقاله تشکر کرده اند

در صورتی که در رابطه با این مقاله سوالی دارید، در تاپیک های انجمن مطرح کنید

نظرات کاربران

برای درج نظر باید وارد سایت شوید