策略模式-订单练笔小项目

这次用策略模式实现了一个较复杂的订单功能。不够纯粹可能没什么学习价值。

先看看实现的效果:

调用过程:

        public void OneDeal()
        {
            Order order = new Order();

            List<BaseDiscount> discountList;
            List<string> typeList;
            Commodity commodity;

            discountList = new List<BaseDiscount>();
            discountList.Add(new VperCentDiscount(0.5) { Name = "即将过期" });
            typeList = new List<string>();
            typeList.Add("便当");
            typeList.Add("生鲜");
            typeList.Add("食品");
            commodity = new Commodity("盒饭", 1, 18.9, discountList, typeList);
            order.AddCommodity(commodity);

            discountList = new List<BaseDiscount>();
            discountList.Add(new VperCentDiscount(0.7) { Name = "当季促销" });
            typeList = new List<string>();
            typeList.Add("水果");
            typeList.Add("生鲜");
            typeList.Add("食品");
            commodity = new Commodity("黄桃", 3, 2.3, discountList, typeList);
            order.AddCommodity(commodity);


            discountList = new List<BaseDiscount>();
            typeList = new List<string>();
            typeList.Add("手机");
            typeList.Add("电器");
            commodity = new Commodity("Vivo手机", 1, 2000, discountList, typeList);
            order.AddCommodity(commodity);


            discountList = new List<BaseDiscount>();
            typeList = new List<string>();
            typeList.Add("笔");
            typeList.Add("文具");
            commodity = new Commodity("签字笔", 10, 0.9, discountList, typeList);
            order.AddCommodity(commodity);


            BaseDiscount discount;

            discount = new VperCentDiscount(0.9);
            discount.Name = "开学促销";
            discount.TypeList = new List<string>();
            discount.TypeList.Add("文具");
            order.AddDiscount(discount);

            discount = new Deduction(10);
            discount.Name = "疫情生鲜补贴";
            discount.TypeList = new List<string>();
            discount.TypeList.Add("便当");
            order.AddDiscount(discount);

            discount = new FullReduction(1000, 50);
            discount.Name = "会员满减";
            discount.TypeList = new List<string>();
            order.AddDiscount(discount);

            // 结算:
            Console.WriteLine("商品列表:");
            foreach (var item in order.Commoditis)
            {
                Console.WriteLine(item.Name + "\t\t\t数量:" + item.Count +
                    "\t原价:" + item.TotalPrice + "\t打折后:" +    item.TotalPrice_Diccount_Initial);
            }
            Console.WriteLine("");
            Console.WriteLine("================");
            Console.WriteLine("");

            Console.WriteLine("原价:" + order.GetPrice_WithoutDiscount());
            Console.WriteLine("================");
            Console.WriteLine("已使用的折扣:");
            foreach (var item in order.DiscountList)
            {
                Console.WriteLine(item.ToString());
            }
            Console.WriteLine("================");
            Console.WriteLine("优惠后价格:" + order.GetFinalPrice());
        }

策略类:

    public class Order
    {
        // 商品列表,
        public List<Commodity> Commoditis;
        // 优惠规则
        public List<BaseDiscount> DiscountList;
        // 当前优惠前, 且没有单个折扣的价格
        double PriceWithoutAnyDiscount;
        // 当前优惠前价格
        double PriceWithoutDiscount;
        // 当前优惠后价格
        double FinalPrice;

        public Order()
        {
            Commoditis = new List<Commodity>();
            DiscountList = new List<BaseDiscount>();
        }

        // 私有方法
        // 更新当前价格
        public void UpdateCurrentPrice()
        {
            PriceWithoutAnyDiscount = 0;
            PriceWithoutDiscount = 0;
            FinalPrice = 0;

            // 为每个商品附加折扣
            foreach (var item in Commoditis)
            {
                foreach (var discount in DiscountList)
                {
                    if (!item.Contains(discount)
                        && item.IsCanUse(discount)
                        && !item.IsConflict(discount))
                    {
                        item.AddDiscount(discount);
                    }
                }

                PriceWithoutAnyDiscount += item.TotalPrice;
                PriceWithoutDiscount += item.TotalPrice_Diccount_Initial;
                //FinalPrice += item.TotalPrice_Diccount;
            }

            // 依次计算出折扣:
            List<Commodity> Commoditis_Discount = new List<Commodity>();
            double discountNum = 0;
            double totalPrice = 0;
            foreach (var discount in DiscountList)
            {
                totalPrice = 0;
                foreach (var item in Commoditis)
                {
                    if (item.Contains(discount))
                    {
                        totalPrice += item.TotalPrice;
                    }
                }
                discountNum += discount.GetDiscount(totalPrice);
            }
            FinalPrice = PriceWithoutDiscount - discountNum;
        }

        // 接口
        // 添加商品,名字,数量,价格,类别标签,单个折扣
        public void AddCommodity(Commodity commodity)
        {
            this.Commoditis.Add(commodity);
        }
        // 移除商品,名字,数量
        public void RemoveCommodity(Commodity commodity)
        {
            this.Commoditis.Remove(commodity);
        }
        // 获取优惠前的价格
        public double GetPrice_WithoutDiscount()
        {
            this.UpdateCurrentPrice();
            return this.PriceWithoutDiscount;
        }
        // 商品自带优惠前的价格
        public double GetPrice_WithoutInitialDiscount()
        {
            this.UpdateCurrentPrice();
            return this.PriceWithoutAnyDiscount;
        }
        // 计算总价格
        public double GetFinalPrice()
        {
            this.UpdateCurrentPrice();
            return this.FinalPrice;
        }
        // 添加优惠规则
        public void AddDiscount(BaseDiscount discount)
        {
            this.DiscountList.Add(discount);
        }
    }

不同的打折类:

    /// 基础优惠类
    public abstract class BaseDiscount
    {
        // 优惠名
        public string Name;
        // 限定类别使用,为空则不限定
        public List<string> TypeList;
        // 不能叠加的优惠
        public List<BaseDiscount> Discounts_Conflict;

        public BaseDiscount()
        {
            TypeList = new List<string>();
            Discounts_Conflict = new List<BaseDiscount>();
        }

        public double HandlePrice(double price)
        {
            return price - GetDiscount(price);
        }

        public virtual double GetDiscount(double price)
        {
            return 0;
        }

    }

    /// 满减优惠类
    public class FullReduction : BaseDiscount
    {
        public double FullPrice = 500;
        public double SubPrice = 50;

        public FullReduction(double fullPrice, double subPrice)
        {
            FullPrice = fullPrice;
            SubPrice = subPrice;
        }
        public override double GetDiscount(double price)
        {
            double dNum = (int)Math.Floor(price / FullPrice) * SubPrice;
            if(dNum > price)
            {
                dNum = price;
            }
            return dNum;
        }
        public override string ToString()
        {
            return Name + " 满" + FullPrice + "减" + SubPrice;
        }
    }
    /// 打折类 
    public class VperCentDiscount : BaseDiscount
    {
        public double VperCentNum = 0.98;
        public VperCentDiscount(double vperCentNum)
        {
            VperCentNum = vperCentNum;
        }

        public override double GetDiscount(double price)
        {
            double dNum = price * (1 - VperCentNum);
            if (dNum > price)
            {
                dNum = price;
            }
            return dNum;
        }
        public override string ToString()
        {
            return Name + " 打" + (VperCentNum * 10) + "折";
        }
    }
    /// 红包抵扣
    public class Deduction : BaseDiscount
    {
        public double num = 20;
        public Deduction(double RedEnvelopesDeduction)
        {
            num = RedEnvelopesDeduction;
        }
        
        public override double GetDiscount(double price)
        {
            double dNum = num;
            if (dNum > price)
            {
                dNum = price ;
            }
            return dNum;
        }
        public override string ToString()
        {
            return Name + " 无门槛红包" + num;
        }
    }

相关的商品类:

/// 商品类
    public class Commodity
    {
        // 名字
        public string Name;
        // 数量
        public int Count;
        // 单价
        public double UnitPrice;
        // 是否优惠了
        public bool IsDiscounted;
        // 初始优惠规则
        public List<BaseDiscount> DiscountList_Initial;
        // 附加的优惠规则
        public List<BaseDiscount> DiscountList;
        // 类别标签
        public List<string> TypeList;

        public Commodity(string name, int count, double unitPrice, List<BaseDiscount> discountList, List<string> typeList)
        {
            Name = name;
            Count = count;
            UnitPrice = unitPrice;
            DiscountList_Initial = discountList;
            TypeList = typeList;

            DiscountList = new List<BaseDiscount>();
        }
        // 自带优惠后单价
        public double UnitPrice_Diccount_Initial
        {
            get
            {
                double price = UnitPrice;
                foreach (var item in DiscountList_Initial)
                {
                    //if (IsCanDiscount(item))
                    //{
                    price = item.HandlePrice(price);
                    //}
                }
                return price;
            }
        }
        // 优惠后单价
        public double UnitPrice_Diccount
        {
            get
            {
                double price = UnitPrice;
                foreach (var item in DiscountList_Initial)
                {
                    //if (IsCanDiscount(item))
                    //{
                    price = item.HandlePrice(price);
                    //}
                }
                foreach (var item in DiscountList)
                {
                    if (IsCanDiscount(item))
                    {
                        price = item.HandlePrice(price);
                    }
                }
                return price;
            }
        }

        // 总价
        public double TotalPrice
        {
            get
            {
                return UnitPrice * Count;
            }
        }

        // 初始优惠后总价
        public double TotalPrice_Diccount_Initial
        {
            get
            {
                return UnitPrice_Diccount_Initial * Count;
            }
        }
        // 优惠后总价
        public double TotalPrice_Diccount
        {
            get
            {
                return UnitPrice_Diccount * Count;
            }
        }
        /// <summary>
        /// 目标优惠是否包含当前类别
        /// </summary>
        /// <param name="discount"></param>
        /// <returns></returns>
        public bool IsCanDiscount(BaseDiscount discount)
        {
            if (discount.TypeList == null || discount.TypeList.Count == 0)
                return true;
            else
            {
                foreach (var item in TypeList)
                {
                    if (discount.TypeList.Contains(item))
                        return true;
                }
                return false;
            }
        }

        /// 添加数量
        public void AddOne()
        {
            Count++;
        }
        /// 减少数量
        public void SubOne()
        {
            if (Count > 0)
            {
                Count--;
            }
        }

        /// 
        public bool Contains(BaseDiscount discount)
        {
            return DiscountList.Contains(discount);
        }

        public bool IsCanUse(BaseDiscount discount)
        {
            if(discount.TypeList.Count == 0)
            {
                return true;
            }
            foreach (var item in discount.TypeList)
            {
                if(this.TypeList.Contains(item))
                {
                    return true;
                }
            }
            return false;
        }


        /// 目标优惠是否与已有优惠冲突
        public bool IsConflict(BaseDiscount discount)
        {
            foreach (var item in DiscountList)
            {
                if (item.Discounts_Conflict.Contains(discount))
                {
                    return true;
                }
            }
            return false;
        }
        /// 增加优惠
        public void AddDiscount(BaseDiscount discount)
        {
            DiscountList.Add(discount);
        }
        /// 减少优惠
        public void SubDisCount(BaseDiscount discount)
        {
            DiscountList.Remove(discount);
        }
        /// 增加类别标签
        public void AddDisCount(string typeName)
        {
            TypeList.Add(typeName);
        }
        /// 减少类别标签
        public void SubDisCount(string typeName)
        {
            TypeList.Remove(typeName);
        }
    }

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值