菜菜哥,YY說你幫她解決了幾個問題,也幫我解決一個唄
原來是D妹子,來坐我身邊,說下情況
我的專案是個電商專案,現在產品狗要給商品做活動
正常呀
我一個新手初來咋到頂不住壓力了,上次來一個折扣活動,現在又來一個滿減
正常呀
最要命的兩個活動還能疊加使用
正常呀
我寫的程式碼讓老大罵了一頓,讓我做最佳化
程式碼有多爛?
離近一點,我給你看看
好嘞
class Product
{
//其他屬性省略
public int Price { get; set; }
}
public int GetPrice()
{
Product p = new Product();
int ret = p.Price;
if (p.Price >= 100*100)
{
ret = ret - 20 * 100;
}
return ret;
}
public int GetPrice()
{
Product p = new Product();
//9折活動
int ret = p.Price * 90 / 100;
//滿減活動
if (ret >= 100 * 100)
{
ret = ret - 20 * 100;
}
return ret;
}
1. 商品菜菜認為有一個共同的基類比較好,這樣就有了一個所有商品的控制點,為以後統一新增屬性留一個入口。好比一個閘道器係統,為什麼會誕生閘道器這個元件呢,因為有了它我們能方便的統一新增認證,授權,統計等一些列行為。
2. 任何促銷的活動最好有一個基類,作用類似商品基類。
3. 對於商品而言,任何促銷活動是商品的行為變化點,影響到的是最終的商品價格,所以獲取價格這個行為要做特殊的處理。
4. 不同種類的促銷活動應該能自行擴充套件,不會影響別的型別促銷活動。
5. 不同種類的促銷活動能疊加使用(其實這裡涉及到每個活動計算的標準是商品原價還是促銷之後價格的問題)。
基於以上幾點,首先把商品的物件做一下抽象
//商品抽象基類
abstract class BaseProduct
{
//商品價格,單位:分
public int Price { get; set; }
//獲取商品價格抽象方法
public abstract int GetPrice();
}
//抽象商品(比如話費商品),繼承商品基類
class VirtualProduct : BaseProduct
{
public override int GetPrice()
{
return this.Price;
}
}
//各種活動的抽象基類,繼承要包裝的型別基類
abstract class BaseActivity : BaseProduct
{
}
//打折活動基類,支援多個商品同時結算
class DiscountActivity : BaseActivity
{
BaseProduct product = null;
public DiscountActivity(int discount, BaseProduct _product)
{
Discount = discount;
product = _product;
}
//折扣,比如 90折 即為90
public int Discount { get; set; }
//獲取折扣之後的價格
public override int GetPrice()
{
return product.GetPrice() * Discount / 100;
}
}
`
class ReductionActivity : BaseActivity
{
BaseProduct product = null;
//滿減的對應表
Dictionary<int, int> reductMap = null;
public ReductionActivity(Dictionary<int, int> _redutMap, BaseProduct _product)
{
reductMap = _redutMap;
product = _product;
}
//獲取折扣之後的價格
public override int GetPrice()
{
var productAmount = product.GetPrice();
//根據商品的總價獲取到要減的價格
var reductValue = reductMap.OrderByDescending(s => s.Key).FirstOrDefault(s => productAmount >= s.Key).Value;
return productAmount - reductValue;
}
}
VirtualProduct p = new VirtualProduct() { Price=1000};
//打折活動
DiscountActivity da = new DiscountActivity(90, p);
var retPrice= da.GetPrice();
Console.WriteLine($"打折後的價格{retPrice}");
//還能疊加參加滿減活動
Dictionary<int, int> m = new Dictionary<int, int>() ;
m.Add(200, 5); //滿200減5
m.Add(300, 10);
m.Add(500, 20);
m.Add(1000, 50);
//這裡活動能疊加使用了
ReductionActivity ra = new ReductionActivity(m, da);
retPrice = ra.GetPrice();
Console.WriteLine($"打折滿減後的價格{retPrice}");
ReductionActivity ra2 = new ReductionActivity(m, ra);
retPrice = ra2.GetPrice();
Console.WriteLine($"再打折後的價格{retPrice}");
打折後的價格900
打折滿減後的價格880
再打折後的價格860
1. 由於這次需要實現的是多商品促銷結算,所以需要一個自定義的商品串列來作為要進行結算的物件。此物件行為級別上與單品類似,有一個需求變化點的抽象:獲取價格
//商品串列的基類,用於活動結算使用
class ActivityListProduct : List
{
//商品串列活動結算的方法,基類必須重寫
public virtual int GetPrice()
{
int ret = 0;
base.ForEach(s =>
{
ret += s.GetPrice();
});
return ret;
}
}
//商品串列 活動的基類,繼承自商品串列基類
internal abstract class BaseActivityList : ActivityListProduct
{
}
//打折活動基類,支援多個商品同時結算
class DiscountActivityList : BaseActivityList
{
ActivityListProduct product = null;
public DiscountActivityList(int discount, ActivityListProduct _product)
{
Discount = discount;
product = _product;
}
//折扣,比如 90折 即為90
public int Discount { get; set; }
public override int GetPrice()
{
var productPrice = product.GetPrice();
return productPrice * Discount / 100;
}
}
//滿減的活動
class ReductionActivityList : BaseActivityList
{
ActivityListProduct product = null;
//滿減的對應表
Dictionary<int, int> reductMap = null;
public ReductionActivityList(Dictionary<int, int> _redutMap, ActivityListProduct _product)
{
reductMap = _redutMap;
product = _product;
}
//獲取折扣之後的價格
public override int GetPrice()
{
var productAmount = product.GetPrice();
//根據商品的總價獲取到要減的價格
var reductValue = reductMap.OrderByDescending(s => s.Key).FirstOrDefault(s => productAmount >= s.Key).Value;
return productAmount - reductValue;
}
}
VirtualProduct p = new VirtualProduct() { Price = 1000 };
VirtualProduct p2 = new VirtualProduct() { Price = 1000 };
ActivityListProduct lst = new ActivityListProduct();
lst.Add(p);
lst.Add(p2);
DiscountActivityList dalist = new DiscountActivityList(80, lst);
Console.WriteLine($"打折後的價格{dalist.GetPrice()}");
DiscountActivityList dalist2 = new DiscountActivityList(90, dalist);
Console.WriteLine($"打折後的價格{dalist2.GetPrice()}");
DiscountActivityList dalist3 = new DiscountActivityList(90, dalist2);
Console.WriteLine($"打折後的價格{dalist3.GetPrice()}");
//還能疊加參加滿減活動
Dictionary<int, int> m = new Dictionary<int, int>();
m.Add(200, 5); //滿200減5
m.Add(300, 10);
m.Add(500, 20);
m.Add(1000, 50);
ReductionActivityList ral = new ReductionActivityList(m, dalist3);
Console.WriteLine($"再滿減打折後的價格{ral.GetPrice()}");
打折後的價格1600
打折後的價格1440
打折後的價格1296
再滿減打折後的價格1246