简体   繁体   English

在购物车上实现工厂模式

[英]Implementing factory pattern on a shopping cart

I have a task where I need to implement a basic shopping cart system.我有一个任务需要实现一个基本的购物车系统。 In this shopping cart, there will be different type of campaigns which is applicable to category of products.在此购物车中,将有适用于产品类别的不同类型的活动。 These campaigns is going to apply different kind of discounts.这些活动将应用不同类型的折扣。 To achieve this, I decided to implement the factory pattern.为了实现这一点,我决定实施工厂模式。

Lets start with the base class for all discount types;让我们从所有折扣类型的基类开始;

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

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

The campaign interface;活动界面;

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

The Campaign type which is applied based on a money amount(eg 100 USD discount over the price);根据金额应用的广告系列类型(例如比价格低 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;
        }

The Campaign type which is applied based on the rate (eg %20 discount over the price);根据费率应用的广告系列类型(例如比价格优惠 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;
        }

As you can see, the different campaign classes differs on the ApplyDiscount() method's algorithm .如您所见,不同的活动类在ApplyDiscount()方法的算法上有所不同。 But also, it differs about one of them has the data member named DiscountAmount and the other has DiscountRate .但是,它的不同之处在于其中一个具有名为DiscountAmount的数据成员,另一个具有DiscountRate

Here is the factory class which I implemented;这是我实现的工厂类;

 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);
            }
        }
    }

The problem with my factory class is the parameter named amountOrRate .我的工厂类的问题是名为amountOrRate的参数。 To initialize the properties DiscountAmount or DiscountRate , I need to have a common parameter in my factory class, but since this properties are semantically different, it looks wrong to me to accept a common parameter in my factory method and both campaign class constructors is going to share it(you can understand my confusion from the naming of the parameter amountOrRate ).要初始化属性DiscountAmountDiscountRate ,我需要在我的工厂类中有一个公共参数,但由于这些属性在语义上不同,在我的工厂方法中接受一个公共参数对我来说似乎是错误的,并且两个活动类构造函数都将分享一下(你可以从参数amountOrRate的命名中理解我的困惑)。

Can you help me to implement the pattern on this particular example?你能帮我在这个特定的例子中实现这个模式吗? You can also advice me if I need to implement different design patterns with factory pattern(eg strategy pattern).如果我需要使用工厂模式(例如策略模式)实现不同的设计模式,您也可以建议我。 Any help is appreciated, thanks.任何帮助表示赞赏,谢谢。

It may be overkill, but one approach would be to have an IInitializer interface, derived with initialization data for each discount type:这可能IInitializer矫枉过正,但一种方法是拥有一个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);
}

I've not shown everything, but you should be able to fill in the gaps.我没有展示所有内容,但您应该能够填补空白。 Also, the actual factory could be done more neatly than an if/else chain.此外,实际的工厂可以比 if/else 链更整洁。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM