Реализация фабричного шаблона в корзине - PullRequest
0 голосов
/ 22 марта 2020

У меня есть задача, где мне нужно внедрить базовую c систему корзины покупок. В этой корзине будут различные типы кампаний, которые применимы к категории товаров. Эти кампании собираются применять различные виды скидок. Чтобы добиться этого, я решил реализовать фабричный шаблон.

Давайте начнем с базового класса для всех типов скидок;

public abstract class Discount
{
    public Category Category { get; set; }
    public int MinimumItems { get; set; }

    public Discount(Category category, int minItems)
    {
        Category = category;
        MinimumItems = minItems;
    }
}  

Интерфейс кампании;

public interface ICampaign
{
    void ApplyDiscount(ShoppingCart card);
}

Тип кампании, который применяется на основе суммы денег (например, скидка 100 долларов США над ценой);

public class AmountDiscount : Discount, ICampaign
    {
        public decimal DiscountAmount { get; set; }
        public AmountDiscountGenerator(Category category, int minItems, decimal discountAmount) : base(category, minItems)
        {
            DiscountAmount = discountAmount;
        }

        public void ApplyDiscount(ShoppingCart card)
        {
            card.TotalPrice() -= DiscountAmount;
        }

Тип кампании, который применяется на основе ставки (например, скидка 20% от цены) ;

public class RateDiscountGenerator : Discount, ICampaignGenerator
    {
        public double DiscountRate { get; set; }
        public RateDiscountGenerator(Category category, int minItems, double discountRate) : base(category, minItems)
        {
            DiscountRate = discountRate;
        }

        public void ApplyDiscount(ShoppingCart card)
        {
             card.TotalPrice() -= card.TotalPrice() * DiscountRate / 100;
        }

Как видите, разные классы кампаний отличаются по алгоритму *1016* метода . Но также отличается то, что один из них имеет элемент данных с именем DiscountAmount, а другой - DiscountRate.

Вот класс фабрики, который я реализовал;

 public static class CampaignFactory
    {
        public static ICampaign GenerateCampaign(Category category, int minItems, int amountOrRate, DiscountType discountType)
        {
            if(discountType == DiscountType.Amount)
            {
                return new AmountDiscountGenerator(category, minItems, amountOrRate);
            }
            else if(discountType == DiscountType.Rate)
            {
                return new RateDiscountGenerator(category, minItems, amountOrRate);
            }
        }
    }

Проблема с моим классом фабрики - параметр с именем amountOrRate. Чтобы инициализировать свойства DiscountAmount или DiscountRate, мне нужно иметь общий параметр в классе фабрики, но так как эти свойства семантически отличаются, мне кажется неправильным принимать общий параметр в методе фабрики и в классе кампании Конструкторы поделятся этим (вы можете понять мое замешательство по названию параметра amountOrRate).

Можете ли вы помочь мне реализовать шаблон на этом конкретном примере? Вы также можете посоветовать мне, если мне нужно реализовать различные шаблоны проектирования с помощью заводского шаблона (например, шаблон стратегии). Любая помощь приветствуется, спасибо.

1 Ответ

0 голосов
/ 22 марта 2020

Это может быть излишним, но одним из подходов будет иметь интерфейс IInitializer, полученный с данными инициализации для каждого типа скидки:

public interface IInitializer
{
}

public class AmountInitializer : IInitializer
{
    public decimal Amount {get; set;}
}

public class RateInitializer : IInitializer
{
    public double Rate{get; set;}
}

public static ICampaign GenerateCampaign(Category category, int minItems, IInitializer init)
{
    if(init is AmountInitializer )
        return new AmountDiscountGenerator(category, minItems, (AmountInitializer)init);
    else if(init is RateInitializer)
        return new RateDiscountGenerator(category, minItems, (RateInitializer)init);
}

Я не все показал, но вы должны быть в состоянии заполнить пробелы. Кроме того, фактическая фабрика может быть сделана более аккуратно, чем цепочка if / else.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...