这次用策略模式实现了一个较复杂的订单功能。不够纯粹可能没什么学习价值。
先看看实现的效果:
调用过程:
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);
}
}