欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

java?設(shè)計(jì)模式從風(fēng)控鏈理解責(zé)任鏈模式

 更新時(shí)間:2023年05月18日 11:18:04   作者:不一樣的科技宅  
這篇文章主要為大家介紹了java?設(shè)計(jì)模式從風(fēng)控鏈理解責(zé)任鏈模式示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

前言

  責(zé)任鏈?zhǔn)且环N行為型模式。顧名思義,由多個(gè)有不同處理能力節(jié)點(diǎn)組成的一條執(zhí)行鏈。當(dāng)一個(gè)事件進(jìn)來時(shí),會(huì)判斷當(dāng)前節(jié)點(diǎn)是否有處理的能力,反之轉(zhuǎn)入下一個(gè)節(jié)點(diǎn)進(jìn)行處理??梢詮闹Ц兜娘L(fēng)控鏈這個(gè)場(chǎng)景,深入的理解責(zé)任鏈模式。

定義

  責(zé)任鏈模式:包含了一些命令和一系列的處理對(duì)象。每一個(gè)處理對(duì)象決定了它能處理哪些命令對(duì)象,它也知道如何將它不能處理的命令對(duì)象傳遞給該鏈中的下一個(gè)處理對(duì)象。

如何理解

  信用卡套現(xiàn),花唄套現(xiàn),白條套現(xiàn),類似的名詞對(duì)于我們來講應(yīng)該不陌生吧。在支付系統(tǒng)中會(huì)有一套風(fēng)控系統(tǒng),來避免發(fā)生類似的事情出現(xiàn)。而風(fēng)控系統(tǒng)就是責(zé)任鏈模式的一種應(yīng)用。

比如說給xxx商戶配置的風(fēng)控規(guī)則是:

TOP信用卡花唄白條
木屋燒烤500/日300/日300/日

  當(dāng)用戶向商家付款時(shí),會(huì)根據(jù)不同的支付方式,來判斷是否觸發(fā)風(fēng)控條件。如果達(dá)到觸發(fā)條件則不允許使用該方式支付。來避免發(fā)生信用卡套現(xiàn)類似的事情。

我們寫個(gè)簡(jiǎn)單的風(fēng)控程序來理解一下:

UML

代碼示例

RiskHandler

public abstract class RiskHandler {
    /**
     * 支付方式
     */
    private String payType;
    private RiskHandler nextHandler;
    public RiskHandler(String payType) {
        this.payType = payType;
    }
    /**
     * 是否能支付
     * @param order 訂單
     */
    protected abstract boolean canPay(Order order);
    /**
     * 處理器
     * @param order 訂單
     * @return 返回true 或者 false
     */
    public final boolean handler(Order order){
        if(order.getPayType().equals(this.payType)){
            return this.canPay(order);
        }else {
            if (this.nextHandler != null){
                return this.nextHandler.handler(order);
            }else{
                throw new IllegalArgumentException("支付方式有誤");
            }
        }
    }
    public void setNextHandler(RiskHandler handler){
        this.nextHandler = handler;
    }
}

CreditHandler

public class CreditHandler extends RiskHandler {
    /**
     * 500 限額
     */
    private BigDecimal limitAmount = BigDecimal.valueOf(500);
    public CreditHandler() {
        super(PayTypeEnum.CREDIT.getPayType());
    }
    @Override
    protected boolean canPay(Order order) {
        if(order.getAmount().compareTo(limitAmount) < 0){
            limitAmount = limitAmount.subtract(order.getAmount());
            return true;
        }else {
            return false;
        }
    }
}

HuabeiHandler

public class HuabeiHandler extends RiskHandler {
    /**
     * 300 限額
     */
    private BigDecimal limitAmount = BigDecimal.valueOf(300);
    public HuabeiHandler() {
        super(PayTypeEnum.HUA_BEI.getPayType());
    }
    @Override
    protected boolean canPay(Order order) {
        if(order.getAmount().compareTo(limitAmount) < 0){
            limitAmount = limitAmount.subtract(order.getAmount());
            return true;
        }else {
            return false;
        }
    }
}

BaiTiaoHandler

public class BaiTiaoHandler extends RiskHandler {
    /**
     * 300 限額
     */
    private BigDecimal limitAmount = BigDecimal.valueOf(300);
    public BaiTiaoHandler() {
        super(PayTypeEnum.BAI_TIAO.getPayType());
    }
    @Override
    protected boolean canPay(Order order) {
        if(order.getAmount().compareTo(limitAmount) &lt; 0){
            limitAmount = limitAmount.subtract(order.getAmount());
            return true;
        }else {
            return false;
        }
    }
}

Order

public interface Order {
    /**
     * 獲取支付方式
     * @return 支付方式
     */
    String getPayType();
    /**
     * 獲取訂單金額
     * @return 訂單金額
     */
    BigDecimal getAmount();
}

ConsumeOrder

public class ConsumeOrder implements Order {
    private String payType;
    private BigDecimal amount;
    public ConsumeOrder(String payType, BigDecimal amount) {
        this.payType = payType;
        this.amount = amount;
    }
    @Override
    public String getPayType() {
        return this.payType;
    }
    @Override
    public BigDecimal getAmount() {
        return this.amount;
    }
}

PayTypeEnum

public enum  PayTypeEnum {
    /**
     * 花唄
     */
    HUA_BEI("hua_bei"),
    /**
     * 白條
     */
    BAI_TIAO("bai_tiao"),
    /**
     * 信用卡
     */
    CREDIT("credit"),
    ;
    private String payType;
    PayTypeEnum(String payType) {
        this.payType = payType;
    }
    public String getPayType() {
        return payType;
    }
}

PayRiskControlService

public class PayRiskControlService {
    public boolean canPay(Order order){
        // 設(shè)置風(fēng)控
        RiskHandler creditHandler = new CreditHandler();
        RiskHandler huabeiHandler = new HuabeiHandler();
        RiskHandler baiTiaoHandler = new BaiTiaoHandler();
        creditHandler.setNextHandler(huabeiHandler);
        huabeiHandler.setNextHandler(baiTiaoHandler);
        return creditHandler.handler(order);
    }
}

Test

public class Test {
    public static void main(String[] args) {
        // 花唄訂單
        ConsumeOrder huabeiOrder = new ConsumeOrder(
                PayTypeEnum.HUA_BEI.getPayType(), BigDecimal.valueOf(200)
        );
        // 白條訂單
        ConsumeOrder baitiaoOrder = new ConsumeOrder(
                PayTypeEnum.BAI_TIAO.getPayType(), BigDecimal.valueOf(301)
        );
        // 加載風(fēng)控系統(tǒng)
        PayRiskControlService riskControlService = new PayRiskControlService();
        // 創(chuàng)建訂單
        boolean canPayOfHuabei = riskControlService.canPay(huabeiOrder);
        boolean canPayOfBaitiao = riskControlService.canPay(baitiaoOrder);
        System.out.println("canPayOfHuabei = " + canPayOfHuabei);
        System.out.println("canPayOfBaitiao = " + canPayOfBaitiao);
    }
}

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

ConsumeOrder{payType='hua_bei', amount=200} canPay: true

ConsumeOrder{payType='bai_tiao', amount=301} canPay: false

優(yōu)點(diǎn)

  • 降低耦合度,將請(qǐng)求和處理分開。
  • 簡(jiǎn)化了對(duì)象,是對(duì)象不需要知道鏈的結(jié)構(gòu)。
  • 增強(qiáng)給對(duì)象指派職責(zé)的靈活性,通過改變鏈內(nèi)的成員或者調(diào)動(dòng)他們的次序,運(yùn)行動(dòng)態(tài)的新增或者刪除責(zé)任。
  • 增加新的處理類很方便。

缺點(diǎn)

  • 不能保證請(qǐng)求一定被接收
  • 系統(tǒng)性能將受到一定影響,而且在調(diào)試代碼時(shí)不太方便,可能會(huì)造成循環(huán)調(diào)用。
  • 可能不容易觀察運(yùn)行時(shí)的特征,有礙于除錯(cuò)。

應(yīng)用場(chǎng)景

  • 有多個(gè)對(duì)象可以處理同一個(gè)請(qǐng)求,具體是哪個(gè)對(duì)象處理由該請(qǐng)求運(yùn)行時(shí)刻自動(dòng)確定。
  • 在不明確接受者的情況下,向多個(gè)對(duì)象中的一個(gè)提交一個(gè)請(qǐng)求。
  • 可以動(dòng)態(tài)指定一組對(duì)象處理請(qǐng)求。

責(zé)任鏈模式的兩種情況

純的職責(zé)鏈模式

  一個(gè)請(qǐng)求必須被某一個(gè)處理者對(duì)象所接收,且一個(gè)具體處理者對(duì)某個(gè)請(qǐng)求的處理只能采用以下兩種行為之一:自己處理(承擔(dān)責(zé)任),把責(zé)任推給下家處理。

不純的職責(zé)鏈模式

  允許出現(xiàn)某一個(gè)具體處理者對(duì)象在承擔(dān)了請(qǐng)求的一部分責(zé)任后又將剩余的責(zé)任傳給下家的情況,且一個(gè)請(qǐng)求可以最終不被任何接收端對(duì)象所接收。比如說,多級(jí)審核登錄安全監(jiān)測(cè)。

注意的點(diǎn)

  鏈中節(jié)點(diǎn)數(shù)量需要控制,避免出現(xiàn)超長(zhǎng)鏈的情況,一般的做法是在Handler中設(shè)置一個(gè)最大節(jié)點(diǎn)數(shù)量,在setNext方法中判斷是否已經(jīng)是超過其閾值,超過則不允許該鏈建立,避免無意識(shí)地破壞系統(tǒng)性能。

參考文章

以上就是java 設(shè)計(jì)模式從風(fēng)控鏈理解責(zé)任鏈模式的詳細(xì)內(nèi)容,更多關(guān)于java責(zé)任鏈模式的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Java Tree結(jié)構(gòu)數(shù)據(jù)中查找匹配節(jié)點(diǎn)方式

    Java Tree結(jié)構(gòu)數(shù)據(jù)中查找匹配節(jié)點(diǎn)方式

    這篇文章主要介紹了Java Tree結(jié)構(gòu)數(shù)據(jù)中查找匹配節(jié)點(diǎn)方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2020-09-09
  • Spring MVC中處理ajax請(qǐng)求的跨域問題與注意事項(xiàng)詳解

    Spring MVC中處理ajax請(qǐng)求的跨域問題與注意事項(xiàng)詳解

    跨域問題是我們大家在開發(fā)中會(huì)經(jīng)常遇到的一個(gè)問題,所以下面這篇文章主要給大家介紹了關(guān)于Spring MVC中處理ajax請(qǐng)求的跨域問題與注意事項(xiàng)的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),需要的朋友可以參考借鑒,下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧。
    2017-11-11
  • SpringBoot2.0整合Shiro框架實(shí)現(xiàn)用戶權(quán)限管理的示例

    SpringBoot2.0整合Shiro框架實(shí)現(xiàn)用戶權(quán)限管理的示例

    這篇文章主要介紹了SpringBoot2.0整合Shiro框架實(shí)現(xiàn)用戶權(quán)限管理的示例,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-08-08
  • Spring Boot實(shí)現(xiàn)圖片上傳/加水印一把梭操作實(shí)例代碼

    Spring Boot實(shí)現(xiàn)圖片上傳/加水印一把梭操作實(shí)例代碼

    這篇文章主要給大家介紹了關(guān)于Spring Boot實(shí)現(xiàn)圖片上傳/加水印一把梭操作的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2018-11-11
  • 關(guān)于Java中HashCode方法的深入理解

    關(guān)于Java中HashCode方法的深入理解

    這篇文章主要給大家介紹了關(guān)于Java中HashCode方法的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用Java具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-08-08
  • 基于Mybatis映射的一點(diǎn)心得(分享)

    基于Mybatis映射的一點(diǎn)心得(分享)

    下面小編就為大家?guī)硪黄贛ybatis映射的一點(diǎn)心得(分享)。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-11-11
  • Redis中4種延時(shí)隊(duì)列實(shí)現(xiàn)方式小結(jié)

    Redis中4種延時(shí)隊(duì)列實(shí)現(xiàn)方式小結(jié)

    Redis作為高性能的內(nèi)存數(shù)據(jù)庫(kù),具備原子操作、數(shù)據(jù)結(jié)構(gòu)豐富和簡(jiǎn)單易用的特性,本文將介紹基于Redis實(shí)現(xiàn)分布式延時(shí)隊(duì)列的四種方式,大家可以根據(jù)需要進(jìn)行選擇
    2025-04-04
  • Mybatis攔截器的實(shí)現(xiàn)介紹

    Mybatis攔截器的實(shí)現(xiàn)介紹

    MyBatis提供了一種插件(plugin)的功能,雖然叫做插件,但其實(shí)這是攔截器功能。MyBatis 允許你在已映射語(yǔ)句執(zhí)行過程中的某一點(diǎn)進(jìn)行攔截調(diào)用。下面通過本文給大家介紹Mybatis攔截器知識(shí),感興趣的朋友一起看看吧
    2016-10-10
  • MyBatis-Plus?分頁(yè)查詢的實(shí)現(xiàn)示例

    MyBatis-Plus?分頁(yè)查詢的實(shí)現(xiàn)示例

    本文主要介紹了MyBatis-Plus?分頁(yè)查詢的實(shí)現(xiàn)示例,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-03-03
  • Java 配置log4j日志文件路徑 (附-獲取當(dāng)前類路徑的多種操作)

    Java 配置log4j日志文件路徑 (附-獲取當(dāng)前類路徑的多種操作)

    這篇文章主要介紹了Java 配置log4j日志文件路徑 (附-獲取當(dāng)前類路徑的多種操作),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2020-10-10

最新評(píng)論