前言:
好久之前,某个网友提的需求,对商品进行加价,根据原商品的价格不同,加价的方式不同。
具体如下:
250元以下 按比率10%以内加价
251~500 加价 25元以下
501~5000 按比率 5%以内加价
5000以上 加价250元以下
比如某种商品价格是:6000或者10000按照5000元以上的标准调。
分析:
首先,加价是一个范围,因此我们先定义一个结构,PriceRange:
1 public struct PriceRange 2 { 3 public decimal MaxPrice { get; set; } 4 public decimal MinPrice { get; set; } 5 }
对于加价相关的逻辑,有两种,一种为固定加价,一种为按比率加价,因此利用策略模式处理如下(英文类名请无视,硬伤):
1 public interface IPriceStrategy 2 { 3 PriceRange GetPriceRange(decimal purchasePrice); 4 } 5 6 /// <summary> 7 /// 固定加价策略 8 /// </summary> 9 public class FixedPriceStrategy : IPriceStrategy 10 { 11 private decimal _fixedPrice; 12 13 /// <summary> 14 /// 15 /// </summary> 16 /// <param name="fixedPrice">加价金额</param> 17 public FixedPriceStrategy(decimal fixedPrice) 18 { 19 this._fixedPrice = fixedPrice; 20 } 21 22 public PriceRange GetPriceRange(decimal purchasePrice) 23 { 24 return new PriceRange() 25 { 26 MinPrice = purchasePrice, 27 MaxPrice = purchasePrice + _fixedPrice, 28 }; 29 } 30 } 31 32 /// <summary> 33 /// 百分比加价策略 34 /// </summary> 35 public class PercentagePriceStrategy : IPriceStrategy 36 { 37 private decimal _percent; 38 39 /// <summary> 40 /// 41 /// </summary> 42 /// <param name="percent">加价率</param> 43 public PercentagePriceStrategy(decimal percent) 44 { 45 this._percent = percent; 46 } 47 48 public PriceRange GetPriceRange(decimal purchasePrice) 49 { 50 return new PriceRange() 51 { 52 MinPrice = purchasePrice, 53 MaxPrice = purchasePrice * (1 + _percent), 54 }; 55 } 56 }
最后需要一个工具类,封装相关加价逻辑,并暴漏一个方法出来:
PS:这里设计:每种加价策略的低价作为key,放到字典中。 获取加价区间时,取小于或等于 传入价格的所有Key中最大的一个(如果没有,则取最大的Key),即为最终的加价策略!
这样设计的好处:可以避免大量的if 和else if 。。。
1 public class PriceUtility 2 { 3 /// <summary> 4 /// 相关加价策略 5 /// </summary> 6 private static Dictionary<decimal, IPriceStrategy> Dic = new Dictionary<decimal, IPriceStrategy>(); 7 8 static PriceUtility() 9 { 10 //初始化加价规则(todo:这里是写死的,如果需求多变,也可以从外部存储获取并初始化) 11 Dic.Add(0, new PercentagePriceStrategy(0.1m)); 12 Dic.Add(250, new FixedPriceStrategy(25)); 13 Dic.Add(500, new PercentagePriceStrategy(0.05m)); 14 Dic.Add(5000, new FixedPriceStrategy(250)); 15 } 16 17 /// <summary> 18 /// 获取加价区间 19 /// </summary> 20 /// <param name="purchasePrice"></param> 21 /// <returns></returns> 22 public static PriceRange GetRange(decimal purchasePrice) 23 { 24 var key = GetCurrentKey(purchasePrice); 25 26 return Dic[key].GetPriceRange(purchasePrice); 27 } 28 29 /// <summary> 30 /// 获取符合条件的Key 31 /// </summary> 32 /// <param name="purchasePrice"></param> 33 /// <returns></returns> 34 private static decimal GetCurrentKey(decimal purchasePrice) 35 { 36 //找到小于等于该价格的所有Key 37 var keys = Dic.Keys.Where(r => r.CompareTo(purchasePrice) <= 0).ToArray(); 38 //如果没有,则取最大的 39 if (keys.Length == 0) return Dic.Keys.Max(); 40 //有则在找到的Key中取最大的 41 return keys.Max(); 42 } 43 }
结果:
用控制台应用程序测试一下:
1 static void Main(string[] args) 2 { 3 ConsolePriceRange(100); 4 ConsolePriceRange(240); 5 ConsolePriceRange(250); 6 ConsolePriceRange(490); 7 ConsolePriceRange(500); 8 ConsolePriceRange(4900); 9 ConsolePriceRange(5000); 10 ConsolePriceRange(10000); 11 12 Console.ReadKey(); 13 } 14 15 static void ConsolePriceRange(decimal price) 16 { 17 PriceRange range = PriceUtility.GetRange(price); 18 19 Console.WriteLine("产品价格{0}的加价区间为:{1}~{2}", price, range.MinPrice, range.MaxPrice); 20 }