試験を通して、プログラマ - エレガンスのマーチャンダイジングのコードで!

 

背景

私の知る限りでは、ほぼすべてのインターネット企業や関連プロジェクトと電気の供給業者が、ほとんどの企業では、このようなJingdongは、淘宝網などの重要なハイライトは、まだあります。電気プロバイダのプロジェクトがありますので、商品は20によって例えば少なくとも100などのプロモーション活動の様々なを持っているだろうと、それは必然的に、商品を伴いますが、女性の休業日と非常に似活動の10%。犬の製品の需要を達成するためにどのようにあるコーダ、コードの最小の変化、それの最もエレガントな実装として。今日カイカイFucai、いくつかの問題Dの姉妹の無能。他の同様の言語に例として以下.netCore C#コード。

まずDオブジェクトは不動産価格があり、姉妹品、商品を持って、ユニットの価格は分割され

 
class Product { //其他属性省略 public int Price { get; set; } } 

ここではフル100回のマイナス20の活動は、このコードの時点での決済価格がされています

 
public int GetPrice() { Product p = new Product(); int ret = p.Price; if (p.Price >= 100*100) { ret = ret - 20 * 100; } return ret; } 

問題はありますか?それを何の問題を要求しないようによると、しかし、計算の結果も正確です。しかし、芸術的なプログラムから、実際には、非常に醜いです。今、私たちは10%の観客の活動を持って、二つ以上の活動に関わる製品を持つことが起こるが、また、(活動のシーケンスは、最初の割引後の完全な削減に参加すると仮定して)使用するように重ね合わせることができます。このタイムコードDの姉妹はそうなりました

 
public int GetPrice() { Product p = new Product(); //9折活动 int ret = p.Price * 90 / 100; //满减活动 if (ret >= 100 * 100) { ret = ret - 20 * 100; } return ret; } 

今再び、同様のイベントがした場合、このコードはまた、オープン・クローズの原則の重大な違反を修正し、頻繁にライン上ですでにコードを修正する必要があること、バグのオッズが大幅に増加されます。また、これはDの妹は彼女を呼び、彼女のコードレビューの理由を聞かせてリーダーです。

最適化されたバージョン

それはどのようにそれを特定の最適化するには?あなたは、コードを変更する前に、私が注意すべきいくつかの重要なポイントがあることを思い出させるしたいと思います:

  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<BaseProduct> { //商品列表活动结算的方法,基类必须重写 public virtual int GetPrice() { int ret = 0; base.ForEach(s => { ret += s.GetPrice(); }); return ret; } } 
  1. 把多商品促销活动的基类抽象出来,供不同的促销活动继承使用,这里需要继承ActivityListProduct,为什么呢?和单品的类似,为了多个子类能够嵌套调用
 
//商品列表 活动的基类,继承自商品列表基类 internal abstract class BaseActivityList : ActivityListProduct { } 
  1. 创建一个打折和满减活动
 
//打折活动基类,支持多个商品同时结算 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

おすすめ

転載: blog.csdn.net/mifffy_java/article/details/91047574
おすすめ