乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      重學(xué) Java 設(shè)計(jì)模式:實(shí)戰(zhàn)策略模式「模擬多種營(yíng)銷類型優(yōu)惠券,折扣金額計(jì)算策略場(chǎng)景」

       小傅哥 2021-12-13


      作者:小傅哥
      博客:https:// - 原創(chuàng)系列專題文章

      沉淀、分享、成長(zhǎng),讓自己和他人都能有所收獲!😄

      一、前言

      文無(wú)第一,武無(wú)第二

      不同方向但同樣努力的人,都有自身的價(jià)值和亮點(diǎn),也都是可以互相學(xué)習(xí)的。不要太過(guò)于用自己手里的矛去攻擊別人的盾🛡,哪怕一時(shí)爭(zhēng)辯過(guò)了也多半可能是你被安放的角色不同。取別人之強(qiáng)補(bǔ)自己之弱,矛與盾的結(jié)合可能就是坦克。

      能把復(fù)雜的知識(shí)講的簡(jiǎn)單很重要

      在學(xué)習(xí)的過(guò)程中我們看過(guò)很多資料、視頻、文檔等,因?yàn)楝F(xiàn)在資料視頻都較多所以往往一個(gè)知識(shí)點(diǎn)會(huì)有多種多樣的視頻形式講解。除了推廣營(yíng)銷以外,確實(shí)有很多人的視頻講解非常優(yōu)秀,例如李永樂(lè)老師的短視頻課,可以在一個(gè)黑板上把那么復(fù)雜的知識(shí),講解的那么容易理解,那么透徹。而我們學(xué)習(xí)編程的人也是,不只是要學(xué)會(huì)把知識(shí)點(diǎn)講明白,也要寫(xiě)明白。

      🙉提升自己的眼界交往更多同好

      有時(shí)候圈子很重要,就像上學(xué)期間大家都會(huì)發(fā)現(xiàn)班里有這樣一類學(xué)生👩?🎓不怎么聽(tīng)課,但是就是學(xué)習(xí)好。那假如讓他回家呆著,不能在課堂里呢?類似的圈子還有;圖書(shū)館、網(wǎng)吧、車友群、技術(shù)群等等,都可以給你帶來(lái)同類愛(ài)好的人所分享出來(lái)的技能或者大家一起烘托出的氛圍幫你成長(zhǎng)。

      二、開(kāi)發(fā)環(huán)境

      1. JDK 1.8
      2. Idea + Maven
      3. 涉及工程三個(gè),可以通過(guò)關(guān)注公眾號(hào)bugstack蟲(chóng)洞棧,回復(fù)源碼下載獲取(打開(kāi)獲取的鏈接,找到序號(hào)18)
      工程描述
      itstack-demo-design-20-01使用一坨代碼實(shí)現(xiàn)業(yè)務(wù)需求
      itstack-demo-design-20-02通過(guò)設(shè)計(jì)模式優(yōu)化改造代碼,產(chǎn)生對(duì)比性從而學(xué)習(xí)

      三、策略模式介紹

      策略模式,圖片來(lái)自 refactoringguru.cn

      策略模式是一種行為模式,也是替代大量ifelse的利器。它所能幫你解決的是場(chǎng)景,一般是具有同類可替代的行為邏輯算法場(chǎng)景。比如;不同類型的交易方式(信用卡、支付寶、微信)、生成唯一ID策略(UUID、DB自增、DB+Redis、雪花算法、Leaf算法)等,都可以使用策略模式進(jìn)行行為包裝,供給外部使用。

      諸葛亮錦囊妙計(jì)

      策略模式也有點(diǎn)像三國(guó)演義中諸葛亮給劉關(guān)張的錦囊;

      • 第一個(gè)錦囊:見(jiàn)喬國(guó)老,并把劉備娶親的事情du搞得東吳人盡皆知。
      • 第二個(gè)錦囊:用謊言(曹操打荊州)騙泡在溫柔鄉(xiāng)里的劉備回去。
      • 第三個(gè)錦囊:讓孫夫人擺平東吳的追兵,她是孫權(quán)妹妹,東吳將領(lǐng)懼她三分。

      四、案例場(chǎng)景模擬

      場(chǎng)景模擬;商品支付使用營(yíng)銷優(yōu)惠券

      在本案例中我們模擬在購(gòu)買商品時(shí)候使用的各種類型優(yōu)惠券(滿減、直減、折扣、n元購(gòu))

      這個(gè)場(chǎng)景幾乎也是大家的一個(gè)日常購(gòu)物省錢渠道,購(gòu)買商品的時(shí)候都希望找一些優(yōu)惠券,讓購(gòu)買的商品更加實(shí)惠。而且到了大促的時(shí)候就會(huì)有更多的優(yōu)惠券需要計(jì)算那些商品一起購(gòu)買更加優(yōu)惠!!!

      這樣的場(chǎng)景有時(shí)候用戶用起來(lái)還是蠻爽的,但是最初這樣功能的設(shè)定以及產(chǎn)品的不斷迭代,對(duì)于程序員👨?💻?開(kāi)發(fā)還是不太容易的。因?yàn)檫@里包括了很多的規(guī)則和優(yōu)惠邏輯,所以我們模擬其中的一個(gè)計(jì)算優(yōu)惠的方式,使用策略模式來(lái)實(shí)現(xiàn)。

      五、用一坨坨代碼實(shí)現(xiàn)

      這里我們先使用最粗暴的方式來(lái)實(shí)現(xiàn)功能

      對(duì)于優(yōu)惠券的設(shè)計(jì)最初可能非常簡(jiǎn)單,就是一個(gè)金額的抵扣,也沒(méi)有現(xiàn)在這么多種類型。所以如果沒(méi)有這樣場(chǎng)景的經(jīng)驗(yàn)話,往往設(shè)計(jì)上也是非常簡(jiǎn)單的。但隨著產(chǎn)品功能的不斷迭代,如果程序最初設(shè)計(jì)的不具備很好的擴(kuò)展性,那么往后就會(huì)越來(lái)越混亂。

      1. 工程結(jié)構(gòu)

      itstack-demo-design-20-01
      └── src
          └── main
              └── java
                  └── org.itstack.demo.design
                      └── CouponDiscountService.java
      
      • 一坨坨工程的結(jié)構(gòu)很簡(jiǎn)單,也是最直接的面向過(guò)程開(kāi)發(fā)方式。

      2. 代碼實(shí)現(xiàn)

      /**
       * 博客:https:// - 沉淀、分享、成長(zhǎng),讓自己和他人都能有所收獲!
       * 公眾號(hào):bugstack蟲(chóng)洞棧
       * Create by 小傅哥(fustack) @2020
       * 優(yōu)惠券折扣計(jì)算接口
       * <p>
       * 優(yōu)惠券類型;
       * 1. 直減券
       * 2. 滿減券
       * 3. 折扣券
       * 4. n元購(gòu)
       */
      public class CouponDiscountService {
      
          public double discountAmount(int type, double typeContent, double skuPrice, double typeExt) {
              // 1. 直減券
              if (1 == type) {
                  return skuPrice - typeContent;
              }
              // 2. 滿減券
              if (2 == type) {
                  if (skuPrice < typeExt) return skuPrice;
                  return skuPrice - typeContent;
              }
              // 3. 折扣券
              if (3 == type) {
                  return skuPrice * typeContent;
              }
              // 4. n元購(gòu)
              if (4 == type) {
                  return typeContent;
              }
              return 0D;
          }
      
      }
      
      • 以上是不同類型的優(yōu)惠券計(jì)算折扣后的實(shí)際金額。
      • 入?yún)?#xff1b;優(yōu)惠券類型、優(yōu)惠券金額、商品金額,因?yàn)橛行﹥?yōu)惠券是滿多少減少多少,所以增加了typeExt類型。這也是方法的不好擴(kuò)展性問(wèn)題。
      • 最后是整個(gè)的方法體中對(duì)優(yōu)惠券抵扣金額的實(shí)現(xiàn),最開(kāi)始可能是一個(gè)最簡(jiǎn)單的優(yōu)惠券,后面隨著產(chǎn)品功能的增加,不斷的擴(kuò)展if語(yǔ)句。實(shí)際的代碼可能要比這個(gè)多很多。

      六、策略模式重構(gòu)代碼

      接下來(lái)使用策略模式來(lái)進(jìn)行代碼優(yōu)化,也算是一次很小的重構(gòu)。

      與上面面向流程式的開(kāi)發(fā)這里會(huì)使用設(shè)計(jì)模式,優(yōu)惠代碼結(jié)構(gòu),增強(qiáng)整體的擴(kuò)展性。

      1. 工程結(jié)構(gòu)

      itstack-demo-design-20-02
      └── src
          └── main
              └── java
                  └── org.itstack.demo.design
                      ├── event
                      │    └── MJCouponDiscount.java
                      │    └── NYGCouponDiscount.java
                      │    └── ZJCouponDiscount.java
                      │    └── ZKCouponDiscount.java
                      ├── Context.java
                      └── ICouponDiscount.java
      

      策略模式模型結(jié)構(gòu)

      策略模式模型結(jié)構(gòu)

      • 整體的結(jié)構(gòu)模式并不復(fù)雜,主要體現(xiàn)的不同類型的優(yōu)惠券在計(jì)算優(yōu)惠券方式的不同計(jì)算策略。
      • 這里包括一個(gè)借口類(ICouponDiscount)以及四種優(yōu)惠券類型的實(shí)現(xiàn)方式。
      • 最后提供了策略模式的上下文控制類處理,整體的策略服務(wù)。

      2. 代碼實(shí)現(xiàn)

      2.1 優(yōu)惠券接口

      public interface ICouponDiscount<T> {
      
          /**
           * 優(yōu)惠券金額計(jì)算
           * @param couponInfo 券折扣信息;直減、滿減、折扣、N元購(gòu)
           * @param skuPrice   sku金額
           * @return           優(yōu)惠后金額
           */
          BigDecimal discountAmount(T couponInfo, BigDecimal skuPrice);
      
      }
      
      
      • 定義了優(yōu)惠券折扣接口,也增加了泛型用于不同類型的接口可以傳遞不同的類型參數(shù)。
      • 接口中包括商品金額以及出參返回最終折扣后的金額,這里在實(shí)際開(kāi)發(fā)中會(huì)比現(xiàn)在的接口參數(shù)多一些,但核心邏輯是這些。

      2.2 優(yōu)惠券接口實(shí)現(xiàn)

      滿減

      public class MJCouponDiscount implements ICouponDiscount<Map<String,String>>  {
      
          /**
           * 滿減計(jì)算
           * 1. 判斷滿足x元后-n元,否則不減
           * 2. 最低支付金額1元
           */
          public BigDecimal discountAmount(Map<String,String> couponInfo, BigDecimal skuPrice) {
              String x = couponInfo.get("x");
              String o = couponInfo.get("n");
      
              // 小于商品金額條件的,直接返回商品原價(jià)
              if (skuPrice.compareTo(new BigDecimal(x)) < 0) return skuPrice;
              // 減去優(yōu)惠金額判斷
              BigDecimal discountAmount = skuPrice.subtract(new BigDecimal(o));
              if (discountAmount.compareTo(BigDecimal.ZERO) < 1) return BigDecimal.ONE;
      
              return discountAmount;
          }
      }
      

      直減

      public class ZJCouponDiscount implements ICouponDiscount<Double>  {
      
          /**
           * 直減計(jì)算
           * 1. 使用商品價(jià)格減去優(yōu)惠價(jià)格
           * 2. 最低支付金額1元
           */
          public BigDecimal discountAmount(Double couponInfo, BigDecimal skuPrice) {
              BigDecimal discountAmount = skuPrice.subtract(new BigDecimal(couponInfo));
              if (discountAmount.compareTo(BigDecimal.ZERO) < 1) return BigDecimal.ONE;
              return discountAmount;
          }
      
      }
      

      折扣

      public class ZKCouponDiscount implements ICouponDiscount<Double> {
      
      
          /**
           * 折扣計(jì)算
           * 1. 使用商品價(jià)格乘以折扣比例,為最后支付金額
           * 2. 保留兩位小數(shù)
           * 3. 最低支付金額1元
           */
          public BigDecimal discountAmount(Double couponInfo, BigDecimal skuPrice) {
              BigDecimal discountAmount = skuPrice.multiply(new BigDecimal(couponInfo)).setScale(2, BigDecimal.ROUND_HALF_UP);
              if (discountAmount.compareTo(BigDecimal.ZERO) < 1) return BigDecimal.ONE;
              return discountAmount;
          }
      
      }
      

      N元購(gòu)

      public class NYGCouponDiscount implements ICouponDiscount<Double> {
      
          /**
           * n元購(gòu)購(gòu)買
           * 1. 無(wú)論原價(jià)多少錢都固定金額購(gòu)買
           */
          public BigDecimal discountAmount(Double couponInfo, BigDecimal skuPrice) {
              return new BigDecimal(couponInfo);
          }
      
      }
      
      • 以上是四種不同類型的優(yōu)惠券計(jì)算折扣金額的策略方式,可以從代碼中看到每一種優(yōu)惠方式的優(yōu)惠金額。

      2.3 策略控制類

      public class Context<T> {
      
          private ICouponDiscount<T> couponDiscount;
      
          public Context(ICouponDiscount<T> couponDiscount) {
              this.couponDiscount = couponDiscount;
          }
      
          public BigDecimal discountAmount(T couponInfo, BigDecimal skuPrice) {
              return couponDiscount.discountAmount(couponInfo, skuPrice);
          }
      
      }
      
      • 策略模式的控制類主要是外部可以傳遞不同的策略實(shí)現(xiàn),在通過(guò)統(tǒng)一的方法執(zhí)行優(yōu)惠策略計(jì)算。
      • 另外這里也可以包裝成map結(jié)構(gòu),讓外部只需要對(duì)應(yīng)的泛型類型即可使用相應(yīng)的服務(wù)。

      3. 測(cè)試驗(yàn)證

      3.1 編寫(xiě)測(cè)試類(直減優(yōu)惠)

      @Test
      public void test_zj() {
          // 直減;100-10,商品100元
          Context<Double> context = new Context<Double>(new ZJCouponDiscount());
          BigDecimal discountAmount = context.discountAmount(10D, new BigDecimal(100));
          logger.info("測(cè)試結(jié)果:直減優(yōu)惠后金額 {}", discountAmount);
      }
      

      測(cè)試結(jié)果

      15:43:22.035 [main] INFO  org.itstack.demo.design.test.ApiTest - 測(cè)試結(jié)果:直減優(yōu)惠后金額 90
      
      Process finished with exit code 0
      

      3.2 編寫(xiě)測(cè)試類(滿減優(yōu)惠)

      @Test
      public void test_mj() {
          // 滿100減10,商品100元
          Context<Map<String,String>> context = new Context<Map<String,String>>(new MJCouponDiscount());
          Map<String,String> mapReq = new HashMap<String, String>();
          mapReq.put("x","100");
          mapReq.put("n","10");
          BigDecimal discountAmount = context.discountAmount(mapReq, new BigDecimal(100));
          logger.info("測(cè)試結(jié)果:滿減優(yōu)惠后金額 {}", discountAmount);
      }
      

      測(cè)試結(jié)果

      15:43:42.695 [main] INFO  org.itstack.demo.design.test.ApiTest - 測(cè)試結(jié)果:滿減優(yōu)惠后金額 90
      
      Process finished with exit code 0
      

      3.3 編寫(xiě)測(cè)試類(折扣優(yōu)惠)

      @Test
      public void test_zk() {
          // 折扣9折,商品100元
          Context<Double> context = new Context<Double>(new ZKCouponDiscount());
          BigDecimal discountAmount = context.discountAmount(0.9D, new BigDecimal(100));
          logger.info("測(cè)試結(jié)果:折扣9折后金額 {}", discountAmount);
      }
      

      測(cè)試結(jié)果

      15:44:05.602 [main] INFO  org.itstack.demo.design.test.ApiTest - 測(cè)試結(jié)果:折扣9折后金額 90.00
      
      Process finished with exit code 0
      

      3.4 編寫(xiě)測(cè)試類(n元購(gòu)優(yōu)惠)

      @Test
      public void test_nyg() {
          // n元購(gòu);100-10,商品100元
          Context<Double> context = new Context<Double>(new NYGCouponDiscount());
          BigDecimal discountAmount = context.discountAmount(90D, new BigDecimal(100));
          logger.info("測(cè)試結(jié)果:n元購(gòu)優(yōu)惠后金額 {}", discountAmount);
      
      

      測(cè)試結(jié)果

      15:44:24.700 [main] INFO  org.itstack.demo.design.test.ApiTest - 測(cè)試結(jié)果:n元購(gòu)優(yōu)惠后金額 90
      
      Process finished with exit code 0
      
      • 以上四組測(cè)試分別驗(yàn)證了不同類型優(yōu)惠券的優(yōu)惠策略,測(cè)試結(jié)果是滿足我們的預(yù)期。
      • 這里四種優(yōu)惠券最終都是在原價(jià)100元上折扣10元,最終支付90元。

      七、總結(jié)

      • 以上的策略模式案例相對(duì)來(lái)說(shuō)不并不復(fù)雜,主要的邏輯都是體現(xiàn)在關(guān)于不同種類優(yōu)惠券的計(jì)算折扣策略上。結(jié)構(gòu)相對(duì)來(lái)說(shuō)也比較簡(jiǎn)單,在實(shí)際的開(kāi)發(fā)中這樣的設(shè)計(jì)模式也是非常常用的。另外這樣的設(shè)計(jì)與命令模式、適配器模式結(jié)構(gòu)相似,但是思路是有差異的。
      • 通過(guò)策略設(shè)計(jì)模式的使用可以把我們方法中的if語(yǔ)句優(yōu)化掉,大量的if語(yǔ)句使用會(huì)讓代碼難以擴(kuò)展,也不好維護(hù),同時(shí)在后期遇到各種問(wèn)題也很難維護(hù)。在使用這樣的設(shè)計(jì)模式后可以很好的滿足隔離性與和擴(kuò)展性,對(duì)于不斷新增的需求也非常方便承接。
      • 策略模式、適配器模式組合模式等,在一些結(jié)構(gòu)上是比較相似的,但是每一個(gè)模式是有自己的邏輯特點(diǎn),在使用的過(guò)程中最佳的方式是經(jīng)過(guò)較多的實(shí)踐來(lái)吸取經(jīng)驗(yàn),為后續(xù)的研發(fā)設(shè)計(jì)提供更好的技術(shù)輸出。

      八、推薦閱讀

      • 1. 重學(xué) Java 設(shè)計(jì)模式:實(shí)戰(zhàn)工廠方法模式「多種類型商品不同接口,統(tǒng)一發(fā)獎(jiǎng)服務(wù)搭建場(chǎng)景」
      • 2. 重學(xué) Java 設(shè)計(jì)模式:實(shí)戰(zhàn)原型模式「上機(jī)考試多套試,每人題目和答案亂序排列場(chǎng)景」
      • 3. 重學(xué) Java 設(shè)計(jì)模式:實(shí)戰(zhàn)橋接模式「多支付渠道(微信、支付寶)與多支付模式(刷臉、指紋)場(chǎng)景」
      • 4. 重學(xué) Java 設(shè)計(jì)模式:實(shí)戰(zhàn)組合模式「營(yíng)銷差異化人群發(fā)券,決策樹(shù)引擎搭建場(chǎng)景」
      • 5. 重學(xué) Java 設(shè)計(jì)模式:實(shí)戰(zhàn)外觀模式「基于SpringBoot開(kāi)發(fā)門(mén)面模式中間件,統(tǒng)一控制接口白名單場(chǎng)景」
      • 6. 重學(xué) Java 設(shè)計(jì)模式:實(shí)戰(zhàn)享元模式「基于Redis秒殺,提供活動(dòng)與庫(kù)存信息查詢場(chǎng)景」
      • 7. 重學(xué) Java 設(shè)計(jì)模式:實(shí)戰(zhàn)備忘錄模式「模擬互聯(lián)網(wǎng)系統(tǒng)上線過(guò)程中,配置文件回滾場(chǎng)景」

        轉(zhuǎn)藏 分享 獻(xiàn)花(0

        0條評(píng)論

        發(fā)表

        請(qǐng)遵守用戶 評(píng)論公約

        類似文章 更多