1. <strong id="7actg"></strong>
    2. <table id="7actg"></table>

    3. <address id="7actg"></address>
      <address id="7actg"></address>
      1. <object id="7actg"><tt id="7actg"></tt></object>

        電商系統(tǒng)設(shè)計模式實戰(zhàn)

        共 5320字,需瀏覽 11分鐘

         ·

        2022-05-22 22:01

        點擊下方“IT牧場”,選擇“設(shè)為星標(biāo)”

        原文?https://www.toutiao.com/article/7095945904498147848



        1 代理模式

        案例:根據(jù)文件類型,將文件存儲到不同服務(wù)

        代理模式:給一個對象創(chuàng)建一個代理對象,通過代理對象可以使用該對象的功能。

        CGLib和JDK是代理模式實現(xiàn)的技術(shù)方案。

        1.1 文件服務(wù)應(yīng)用

        代理模式的應(yīng)用場景除了代碼級別,還可以將代理模式遷移到應(yīng)用以及架構(gòu)級別,如下圖文件上傳代理服務(wù),針對一些圖片小文件,我們可以直接把文件存儲到FastDFS服務(wù),針對大文件,例如商品視頻介紹,我們可以把它存儲到第三方OSS。

        用戶通過文件上傳代理服務(wù)可以間接訪問OSS和本地FastDFS,這種分布式海量文件管理解決方案,這里不僅在代碼層面充分運(yùn)用了代理模式,在架構(gòu)層面也充分運(yùn)用了代理模式。

        1.2 分布式文件代理服務(wù)器實現(xiàn)

        1.2.1 實現(xiàn)分析

        基于代理模式,我們實現(xiàn)文件上傳分別路由到 aliyunOSS 和 FastDFS ,用例圖如下:

        講解:

        1、FileUpload抽象接口,定義了文件上傳方法,分別給它寫了2種實現(xiàn)。

        2、AliyunOSSFileUpload是將文件上傳到aliyunOSS,主要上傳mp4和avi的視頻大文件。

        3、FastdfsFileUpoad是將文件上傳到FastDFS,主要上傳png/jpg等圖片小文件。

        4、FileUploadProxy是代理對象,供用戶訪問,調(diào)用了FileUpload的文件上傳方法,為用戶提供不同文件上傳調(diào)用。

        5、FileController是控制器,用于接收用戶提交的文件,并調(diào)用代理FileUploadProxy實現(xiàn)文件上傳。

        1.2.2 代碼實現(xiàn)

        bootstrap.yml配置:

        FileUpload接口定義:

        AliyunOSSFileUpload實現(xiàn):


        FastdfsFileUpoad實現(xiàn):

        FileUploadProxy代理實現(xiàn):

        FileController控制器實現(xiàn)

        2 享元模式

        定義:運(yùn)用共享技術(shù)來有效地支持大量細(xì)粒度對象的復(fù)用。它通過共享已經(jīng)存在的對象來大幅度減少需要創(chuàng)建的對象數(shù)量、避免大量相似類的開銷,從而提高系統(tǒng)資源的利用率。

        享元模式和單利的區(qū)別:

        單例是對象只能自己創(chuàng)建自己,整個應(yīng)用中只有1個對象

        享元模式根據(jù)需要共享,不限制被誰創(chuàng)建(有可能有多個對象實例)

        優(yōu)點:

        特定環(huán)境下,相同對象只要保存一份,這降低了系統(tǒng)中對象的數(shù)量,從而降低了系統(tǒng)中細(xì)粒度對象給內(nèi)存帶來的壓力。

        缺點:

        為了使對象可以共享,需要將一些不能共享的狀態(tài)外部化,這將增加程序的復(fù)雜性

        2.1 享元模式實戰(zhàn)

        案例:用戶下單,會話共享

        2.1.1 會話跟蹤分析

        會話跟蹤,如果是傳統(tǒng)項目用Session或者是Cookie,全項目通用,但在微服務(wù)項目中,不用Session也不用Cookie,所以想要在微服務(wù)項目中實現(xiàn)會話跟蹤,是有一定難度的。

        當(dāng)前微服務(wù)項目中,身份識別的主流方法是前端將用戶令牌存儲到請求頭中,每次請求將請求頭中的令牌攜帶到后臺,后臺每次從請求頭中獲取令牌來識別用戶身份。

        我們在項目操作過程中,很多地方都會用到用戶身份信息,比如下訂單的時候,要知道當(dāng)前訂單屬于哪個用戶,記錄下單關(guān)鍵日志的時候,需要記錄用戶操作的信息以及用戶信息,關(guān)鍵日志記錄我們一般用AOP進(jìn)行攔截操作,此時沒法直接把用戶身份信息傳給AOP。這個時候我們可以利用享元模式實現(xiàn)用戶會話信息共享操作。操作流程如下圖:

        2.1.2 會話共享案例實現(xiàn)

        基于上面的分析,我們采用享元模式實現(xiàn)用戶會話共享操作,要解決如下幾個問題:

        定義共享組件:LogComponent

        LogComponent 里面定義了每個線程中不變的用戶身份信息 username 、 role 、 sex ,其他的是可能存在變化的數(shù)據(jù),例如用于做日志記錄的 methodName 、 message 。

        享元組件邏輯操作對象:SupplementSource

        SupplementSource 該對象主要用于給當(dāng)前線程填充共享數(shù)據(jù),以及變更訪問方法和訪問信息等信息的邏輯操作,代碼如下:

        多線程安全控制:ThreadUserLog

        每個線程請求的時候,我們需要保障會話安全,比如A線程訪問和B線程訪問,他們的用戶會話身份不能因為并發(fā)原因而發(fā)生混亂。這里我們可以采用ThreadLocal來實現(xiàn)。我們創(chuàng)建一個 ThreadUserLog 對象,并在該對象中創(chuàng)建ThreadLocal 用戶存儲每個線程的會話信息,并實現(xiàn) ThreadLocal 的操作,代碼如下:


        線程會話初始化:AuthorizationInterceptor

        AuthorizationInterceptor 攔截器的作用是用于初始化用戶訪問的時候用戶的身份信息,并將身份信息存儲到ThreadUserLog 的 ThreadLocal 中,在用戶訪問方法結(jié)束,銷毀 ThreadUserLog 的 ThreadLocal 中會話,代碼如下:


        創(chuàng)建 MvcConfig 來配置攔截器 AuthorizationInterceptor ,代碼如下:


        共享信息使用:

        ①AOP記錄日志:創(chuàng)建AOP切面類 LogAspect 用于記錄日志,代碼如下:


        ②添加訂單獲取用戶信息:在添加訂單方法 OrderServiceImpl.add(Order order) 中,從ThreadUserLog中獲取用戶會話,并填充給Order,代碼如下

        添加訂單,日志輸出可以看到調(diào)用添加訂單和修改庫存時,都記錄了日志,并且獲取了用戶會話,效果如下:

        加的訂單數(shù)據(jù)庫數(shù)據(jù)中也擁有用戶信息,效果如下:

        3 裝飾著模式

        定義:動態(tài)的向一個現(xiàn)有的對象添加新的功能,同時又不改變其結(jié)構(gòu)。它屬于結(jié)構(gòu)型模式。

        優(yōu)點:裝飾類和被裝飾類可以獨立發(fā)展,不會相互耦合,裝飾模式是繼承的一個替代模式,裝飾模式可以動態(tài)擴(kuò)展一個實現(xiàn)類的功能

        缺點:多層裝飾比較復(fù)雜。

        3.1 裝飾者模式實戰(zhàn)

        案例:結(jié)算價格計算,根據(jù)不同價格嵌套運(yùn)算

        在訂單提交的時候,訂單價格和結(jié)算價格其實是兩碼事,訂單價格是當(dāng)前商品成交價格,而結(jié)算價格是用戶最終需要支付的金額,最終支付的金額并不是一成不變,它也并不是商品成交價格,能改變結(jié)算價格的因素很多,比如滿100減10元,VIP用戶再減5塊。訂單結(jié)算金額計算我們就可以采用裝飾者模式。

        3.1.2 裝飾者模式價格運(yùn)算實現(xiàn)

        實現(xiàn)思路分析:

        基礎(chǔ)接口:創(chuàng)建接口 MoneySum ,該接口只用于定義計算訂單金額的方法。

        訂單金額計算類:創(chuàng)建類 OrderPayMoneyOperation 實現(xiàn)訂單金額的計算。

        裝飾者類:創(chuàng)建裝飾者類 DecoratorMoneySum 供其他類擴(kuò)展。


        滿100減10元價格計算:創(chuàng)建類 FullMoneySum 擴(kuò)展裝飾者類,實現(xiàn)滿減價格計算。


        VIP優(yōu)惠10元價格計算:創(chuàng)建類 VipMoneySum ,實現(xiàn)VIP優(yōu)惠計算。

        支付金額計算修改 OrderServiceImpl 的 add() 方法,添加訂單金額以及訂單支付金額的計算功能,代碼如下:

        測試效果:

        測試數(shù)據(jù)中,我們選擇購買1件商品,當(dāng)前登錄用戶為王五,擁有5個金幣,當(dāng)前購買的商品id=1,商品單價是150元,滿減100,VIP優(yōu)惠5元,最終支付135元。

        測試生成的訂單如下:

        不僅如此,我們可以隨時撤掉滿減和Vip優(yōu)惠功能。

        4 策略模式

        定義:策略模式是對算法的包裝,把使用算法的責(zé)任和算法本身分隔開,委派給不同的對象管理。策略模式通常把一系列的算法包裝到一系列的策略類里面,作為一個抽象策略類的子類。

        簡單來說就是就定義一個策略接口,子類策略去實現(xiàn)該接口去定義不同的策略。然后定義一個環(huán)境(Context,也就是需要用到策略的對象)類,以策略接口作為成員變量,根據(jù)環(huán)境來使用具體的策略。

        優(yōu)點:

        缺點:


        4.1 策略模式實戰(zhàn)

        案例:結(jié)算價格計算,根據(jù)Vip不同等級進(jìn)行運(yùn)算

        4.1.1 不同VIP優(yōu)惠價格分析

        用戶在購買商品的時候,很多時候會根據(jù)Vip等級打不同折扣,尤其是在線商城中體現(xiàn)的淋漓盡致。我們這里也基于真實電商案例來實現(xiàn)VIP等級價格制:

        4.1.2 代碼實現(xiàn)

        定義策略接口:Strategy

        定義Vip0策略StrategyVipOne

        定義Vip1策略:?StrategyVipTwo

        定義Vip2策略StrategyVipThree

        定義Vip3策略StrategyVipFour

        定義策略工廠StrategyFactory

        等級策略配置修改application.yml,將如下策略配置進(jìn)去

        等級控制修改 UserHandler 添加等級屬性

        修改 UserHandlerShare 定義等級,代碼如下:

        裝飾者模式中修改 VipMoneySum 的價格運(yùn)算,代碼如下:

        測試:

        5 工廠模式

        案例:收銀案例,根據(jù)不同支付方式,選擇不同支付渠道

        定義:定義一個創(chuàng)建產(chǎn)品對象的工廠接口,將產(chǎn)品對象的實際創(chuàng)建工作推遲到具體子工廠類當(dāng)中。這滿足創(chuàng)建型模式中所要求的“創(chuàng)建與使用相分離”的特點。

        5.1 工廠模式實戰(zhàn)

        5.1.1 支付渠道選中分析

        用戶每次下單完成后,需要支付訂單,支付訂單會根據(jù)自身情況選擇不同支付方式,后臺服務(wù)會根據(jù)用戶選中不同創(chuàng)建不同支付渠道的實例,這里創(chuàng)建支付渠道的實例可以采用工廠方法模式。

        5.1.2 代碼實現(xiàn)

        工廠方法在SpringBoot中如果在用工廠的同時又出現(xiàn)了new,那絕對是一個敗筆。在SpringBoot中,幾乎所有對象

        都可以直接交給Spring容器管理,它天然已經(jīng)是一個工廠對象,因此在SpringBoot項目中用工廠模式,再頻繁new對象反而不妥。那么工廠模式究竟怎么用在SpringBoot項目的支付場景呢?其實很簡單,如果我們要選擇一個支付渠道,而項目中有100種支付渠道,那這個時候無疑要寫100個 @Autowired 注入100個支付渠道,并且需要做100種判斷,這個時候我們可以用工廠模式取代我們判斷,直接根據(jù)我們配置的映射關(guān)系從Spring容器中拿到對應(yīng)支付渠道的實例,代碼量將大大減少,這塊是使用工廠的另一種妙用

        支付接口:?PayChannel 定義支付行為。

        微信支付實現(xiàn)WeixinPay 實現(xiàn)微信支付操作,這里只模擬。

        支付寶支付實現(xiàn):?AliPay 實現(xiàn)支付寶支付,這里只模擬。

        支付渠道映射配置在 application.yml 中配置支付渠道映射,每次從前端傳入支付ID即可從配置中獲取支付渠道對應(yīng)Spring容器中實例的id。

        支付渠道獲取工廠創(chuàng)建創(chuàng)建 PayFactory 用于獲取支付渠道的實例,我們這里通過映射的key獲取Spring容器中實例的id值,然后從Spring容器中根據(jù)id獲取對應(yīng)實例,因此該工廠需要實現(xiàn)接口 ApplicationContextAware 來獲取容器。

        支付渠道調(diào)用實現(xiàn)修改 PayServiceImpl 的 pay 方法,實現(xiàn)支付,代碼如下:

        測試當(dāng)我們選中支付渠道為1(微信支付)或者2(支付寶支付)的時候,都能爭取獲取對應(yīng)的渠道實例。

        6 狀態(tài)模式

        案例:訂單不同狀態(tài),執(zhí)行不同操作

        定義:對有狀態(tài)的對象,把復(fù)雜的“判斷邏輯”提取到不同的狀態(tài)對象中,允許狀態(tài)對象在其內(nèi)部狀態(tài)發(fā)生改變時改變其行為。

        優(yōu)點

        缺點

        6.1 狀態(tài)模式實戰(zhàn)

        6.1.1 狀態(tài)模式案例分析

        在電商案例中,訂單狀態(tài)每次發(fā)生變更,都要執(zhí)行不同的操作,這里正好可以使用狀態(tài)模式。當(dāng)訂單完成支付的時候,我們需要立即通知商家發(fā)貨,當(dāng)訂單執(zhí)行取消的時候,我們需要執(zhí)行庫存回滾,如果訂單已支付,還需要執(zhí)行退款操作,無論是通知商家發(fā)貨還是執(zhí)行庫存回滾,都是有訂單狀態(tài)決定,因此這里可以使用狀態(tài)模式來實現(xiàn)

        我們可以先定義狀態(tài)接口 State ,給狀態(tài)接口實現(xiàn)兩個不同的行為,分別是發(fā)貨和回滾庫存并退款,把該狀態(tài)對象添加到訂單內(nèi)部作為成員屬性,當(dāng)訂單的 state 狀態(tài)改變時,觸發(fā)執(zhí)行不同的狀態(tài)行為動作。

        5.1.2 案例實現(xiàn)

        狀態(tài)接口定義:State 接口,用于定義更新狀態(tài)對象,同時執(zhí)行相關(guān)的行為。

        發(fā)通知消息行為定義SendMsgBehavior 用于實現(xiàn)給商家發(fā)送消息通知發(fā)貨,這里模擬發(fā)送消息的行為。

        庫存回滾并退款創(chuàng)建 ResetStoreBehavior ,用于實現(xiàn)訂單庫存回滾,并給用戶退款操作,這里退款模擬相關(guān)行

        為。

        測試:

        支付訂單的時候,如果支付成功,我們調(diào)用 State 變更對應(yīng)的狀態(tài)行為,并執(zhí)行相關(guān)行為,代碼如下:

        測試結(jié)果如下:


        干貨分享

        最近將個人學(xué)習(xí)筆記整理成冊,使用PDF分享。關(guān)注我,回復(fù)如下代碼,即可獲得百度盤地址,無套路領(lǐng)??!

        ?001:《Java并發(fā)與高并發(fā)解決方案》學(xué)習(xí)筆記;?002:《深入JVM內(nèi)核——原理、診斷與優(yōu)化》學(xué)習(xí)筆記;?003:《Java面試寶典》?004:《Docker開源書》?005:《Kubernetes開源書》?006:《DDD速成(領(lǐng)域驅(qū)動設(shè)計速成)》?007:全部?008:加技術(shù)群討論

        加個關(guān)注不迷路


        喜歡就點個"在看"唄^_^

        瀏覽 46
        點贊
        評論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報
        評論
        圖片
        表情
        推薦
        點贊
        評論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報
        1. <strong id="7actg"></strong>
        2. <table id="7actg"></table>

        3. <address id="7actg"></address>
          <address id="7actg"></address>
          1. <object id="7actg"><tt id="7actg"></tt></object>
            黄色电影无码 | 丰满奶水二区三区在线 | jzzijzzij亚洲熟女少妇18 | 国产下药迷倒白嫩丰满美女j9 | 成人网站欧美proumb | 欧美激情四射 | 逼逼逼逼逼逼逼逼 | 丰满人妻一区二区三区免费 | 91精品国产乱码久久久久 | 欧美精品123区分布 |