最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java設(shè)計(jì)模式中責(zé)任鏈模式詳解

 更新時(shí)間:2022年11月24日 09:13:11   作者:lpf_wei  
責(zé)任鏈模式是將鏈中的每一個(gè)節(jié)點(diǎn)看做是一個(gè)對(duì)象,每個(gè)節(jié)點(diǎn)處理的請(qǐng)求均不相同,且內(nèi)部自動(dòng)維護(hù)下一個(gè)節(jié)點(diǎn)對(duì)象,當(dāng)一個(gè)請(qǐng)求從鏈?zhǔn)降氖锥伟l(fā)出時(shí),會(huì)沿著鏈的路徑依次傳遞給每一個(gè)節(jié)點(diǎn)對(duì)象。本文將通過示例和大家詳細(xì)聊聊責(zé)任鏈模式,需要的可以參考一下

編程是一門藝術(shù),大批量的改動(dòng)顯然是非常丑陋的做法,用心的琢磨寫的代碼讓它變的更美觀。

在現(xiàn)實(shí)生活中,一個(gè)事件需要經(jīng)過多個(gè)對(duì)象處理是很常見的場(chǎng)景。例如,采購(gòu)審批流程、請(qǐng)假流程等。公司員工請(qǐng)假,可批假的領(lǐng)導(dǎo)有部門負(fù)責(zé)人、副總經(jīng)理、總經(jīng)理等,但每個(gè)領(lǐng)導(dǎo)能批準(zhǔn)的天數(shù)不同,員工必須根據(jù)需要請(qǐng)假的天數(shù)去找不同的領(lǐng)導(dǎo)簽名,也就是說員工必須記住每個(gè)領(lǐng)導(dǎo)的姓名、電話和地址等信息,這無疑增加了難度。

在計(jì)算機(jī)軟硬件中也有相關(guān)例子,如異常處理中,處理程序根據(jù)異常的類型決定自己是否處理該異常;還有 OkHttp的攔截器,這些都可以考慮使用責(zé)任鏈模式來實(shí)現(xiàn)。

1.責(zé)任鏈設(shè)計(jì)模式的定義

責(zé)任鏈(Chain of Responsibility)模式:為了避免請(qǐng)求發(fā)送者與多個(gè)請(qǐng)求處理者耦合在一起,于是將所有請(qǐng)求的處理者通過前一對(duì)象記住其下一個(gè)對(duì)象的引用而連成一條鏈;當(dāng)有請(qǐng)求發(fā)生時(shí),可將請(qǐng)求沿著這條鏈傳遞,直到有對(duì)象處理它為止。

2.責(zé)任鏈設(shè)計(jì)模式的優(yōu)點(diǎn)與不足

責(zé)任鏈模式是一種對(duì)象行為型模式其主要優(yōu)點(diǎn):

  • 降低了對(duì)象之間的耦合度。該模式使得一個(gè)對(duì)象無須知道到底是哪一個(gè)對(duì)象處理其請(qǐng)求以及鏈的結(jié)構(gòu),發(fā)送者和接收者也無須擁有對(duì)方的明確信息。
  • 增強(qiáng)了系統(tǒng)的可擴(kuò)展性。可以根據(jù)需要增加新的請(qǐng)求處理類,滿足開閉原則。
  • 增強(qiáng)了給對(duì)象指派職責(zé)的靈活性。當(dāng)工作流程發(fā)生變化,可以動(dòng)態(tài)地改變鏈內(nèi)的成員或者調(diào)動(dòng)它們的次序,也可動(dòng)態(tài)地新增或者刪除責(zé)任。
  • 責(zé)任鏈簡(jiǎn)化了對(duì)象之間的連接。每個(gè)對(duì)象只需保持一個(gè)指向其后繼者的引用,不需保持其他所有處理者的引用,這避免了使用眾多的 if 或者 if···else 語句。
  • 責(zé)任分擔(dān)。每個(gè)類只需要處理自己該處理的工作,不該處理的傳遞給下一個(gè)對(duì)象完成,明確各類的責(zé)任范圍,符合類的單一職責(zé)原則。

其主要不足:

  • 不能保證每個(gè)請(qǐng)求一定被處理。由于一個(gè)請(qǐng)求沒有明確的接收者,所以不能保證它一定會(huì)被處理,該請(qǐng)求可能一直傳到鏈的末端都得不到處理。
  • 對(duì)比較長(zhǎng)的職責(zé)鏈,請(qǐng)求的處理可能涉及多個(gè)處理對(duì)象,系統(tǒng)性能將受到一定影響。
  • 職責(zé)鏈建立的合理性要靠客戶端來保證,增加了客戶端的復(fù)雜性,可能會(huì)由于職責(zé)鏈的錯(cuò)誤設(shè)置而導(dǎo)致系統(tǒng)出錯(cuò),如可能會(huì)造成循環(huán)調(diào)用。

3.責(zé)任鏈設(shè)計(jì)模式的實(shí)現(xiàn)思路

通常情況下,可以通過數(shù)據(jù)鏈表來實(shí)現(xiàn)職責(zé)鏈模式的數(shù)據(jù)結(jié)構(gòu)

職責(zé)鏈模式主要包含以下角色:

  • 抽象處理者(Handler)角色:定義一個(gè)處理請(qǐng)求的接口,包含抽象處理方法和一個(gè)后繼連接。
  • 具體處理者(Concrete Handler)角色:實(shí)現(xiàn)抽象處理者的處理方法,判斷能否處理本次請(qǐng)求,如果可以處理請(qǐng)求則處理,否則將該請(qǐng)求轉(zhuǎn)給它的后繼者。
  • 客戶類(Client)角色:創(chuàng)建處理鏈,并向鏈頭的具體處理者對(duì)象提交請(qǐng)求,它不關(guān)心處理細(xì)節(jié)和請(qǐng)求的傳遞過程。

責(zé)任鏈模式的本質(zhì)是解耦請(qǐng)求與處理,讓請(qǐng)求在處理鏈中能進(jìn)行傳遞與被處理;理解責(zé)任鏈模式應(yīng)當(dāng)理解其模式,而不是其具體實(shí)現(xiàn)。責(zé)任鏈模式的獨(dú)到之處是將其節(jié)點(diǎn)處理者組合成了鏈?zhǔn)浇Y(jié)構(gòu),并允許節(jié)點(diǎn)自身決定是否進(jìn)行請(qǐng)求處理或轉(zhuǎn)發(fā),相當(dāng)于讓請(qǐng)求流動(dòng)起來。

4.責(zé)任鏈設(shè)計(jì)模式應(yīng)用實(shí)例

場(chǎng)景描述:購(gòu)買商品打折:假如打折可以疊加,只要符合要求,各種折扣都可以疊加使用。

/**
 * 責(zé)任鏈實(shí)現(xiàn)的關(guān)鍵是 定義一個(gè)next節(jié)點(diǎn)  然后構(gòu)建一個(gè)鏈?zhǔn)浇Y(jié)構(gòu)
 */
public abstract class MultyDiscount implements Discount {
    /**
     * 鏈的下一個(gè)節(jié)點(diǎn)
     */
    protected MultyDiscount nextMultyDiscount;
    /**
     * 通過構(gòu)造函數(shù) 將下一個(gè)節(jié)點(diǎn)鏈接起來
     * @param nextMultyDiscount
     */
    public MultyDiscount(MultyDiscount nextMultyDiscount){
        this.nextMultyDiscount = nextMultyDiscount;
    }
    @Override
    public int calculate(int money) {
        if (nextMultyDiscount!=null){
            this.nextMultyDiscount.calculate(money);
        }
        return money;
    }
}
public class FullMultyDiscount extends MultyDiscount{
    /**
     * 通過構(gòu)造函數(shù) 將下一個(gè)節(jié)點(diǎn)鏈接起來
     *
     * @param nextMultyDiscount
     */
    public FullMultyDiscount(MultyDiscount nextMultyDiscount) {
        super(nextMultyDiscount);
    }
    @Override
    public int calculate(int money) {
        /*先執(zhí)行滿減操作*/
        if (money > 200){
            System.out.println("優(yōu)惠滿減20元");
            money = money - 20;
        }
        /*父類的方法執(zhí)行的是成員變量的優(yōu)惠方案,也就是節(jié)點(diǎn)的優(yōu)惠方案*/
        return super.calculate(money);
    }
}
/**
 * 假日一律減5元
 */
public class HolidayMultyDiscount extends MultyDiscount {
    /**
     * 公共的下一個(gè)節(jié)點(diǎn) 存放在父類節(jié)點(diǎn)上
     * @param nextMultyDiscount
     */
    public HolidayMultyDiscount(MultyDiscount nextMultyDiscount) {
        super(nextMultyDiscount);
    }
    @Override
    public int calculate(int money) {
        if (money > 20){
            System.out.println("假日一律減5元");
            money = money - 5;
        }
        return super.calculate(money);
    }
}
/**
 * 首次購(gòu) 花費(fèi)多100元 減免30
 */
public class NewerMultyDiscount extends MultyDiscount {

    public NewerMultyDiscount(MultyDiscount nextMultyDiscount) {
        super(nextMultyDiscount);
    }
    @Override
    public int calculate(int money) {
        if (money > 100){
            System.out.println("首次購(gòu)買減30元");
            money = money - 30;
        }
        return super.calculate(money);
    }
}
/**
 * 第二單8折優(yōu)惠
 */
public class SecondMultyDiscount extends MultyDiscount {
    public SecondMultyDiscount(MultyDiscount nextMultyDiscount) {
        super(nextMultyDiscount);
    }
    @Override
    public int calculate(int money) {
        System.out.println("第二單打8折");
        Double balance =  money * 0.8;
        return super.calculate(balance.intValue());
    }
}
public class ChainCartClient {
    /*初始化滿減優(yōu)惠券  滿減沒有下一個(gè)節(jié)點(diǎn) 是最后一個(gè)節(jié)點(diǎn)*/
    private static MultyDiscount multyDiscount = new FullMultyDiscount(null);
    static {
        /*新用戶減免優(yōu)惠是 滿減優(yōu)惠*/
        multyDiscount = new NewerMultyDiscount(multyDiscount);
        /*第二單打折扣的下一個(gè)節(jié)點(diǎn)是新用戶減免*/
        multyDiscount = new SecondMultyDiscount(multyDiscount);
        /*假日的下一個(gè)節(jié)點(diǎn)是 第二單打折扣*/
        multyDiscount = new HolidayMultyDiscount(multyDiscount);
    }
    public static void main(String[] args) {
        List<Fruit> products = new ArrayList();
        products.add(StaticFactory.getFruitApple());
        products.add(StaticFactory.getFruitBanana());
        products.add(StaticFactory.getFruitOrange());
        ShoppingCart cart = new OtherPayShopping(products);
        /*注入優(yōu)惠方案*/
        cart.setDiscount(multyDiscount);
        cart.submitOrder();
    }
}

責(zé)任鏈設(shè)計(jì)模式這個(gè)實(shí)例中,兩個(gè)關(guān)鍵點(diǎn):一個(gè)是需要一個(gè)成員變量存儲(chǔ)下一個(gè)節(jié)點(diǎn),第二個(gè)就是建立一個(gè)鏈?zhǔn)浇Y(jié)構(gòu)的數(shù)據(jù)。

5.責(zé)任鏈設(shè)計(jì)模式應(yīng)用場(chǎng)景

責(zé)任鏈模式通常在以下幾種情況使用:

多個(gè)對(duì)象可以處理一個(gè)請(qǐng)求,但具體由哪個(gè)對(duì)象處理該請(qǐng)求在運(yùn)行時(shí)自動(dòng)確定??蓜?dòng)態(tài)指定一組對(duì)象處理請(qǐng)求,或添加新的處理者。需要在不明確指定請(qǐng)求處理者的情況下,向多個(gè)處理者中的一個(gè)提交請(qǐng)求。

到此這篇關(guān)于Java設(shè)計(jì)模式中責(zé)任鏈模式詳解的文章就介紹到這了,更多相關(guān)Java責(zé)任鏈模式內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java實(shí)現(xiàn)滑動(dòng)驗(yàn)證碼的示例代碼

    Java實(shí)現(xiàn)滑動(dòng)驗(yàn)證碼的示例代碼

    這篇文章主要為大家介紹了如何用Java語言實(shí)現(xiàn)滑動(dòng)驗(yàn)證碼的生成,項(xiàng)目采用了springboot,maven等技術(shù),感興趣的小伙伴可以跟隨小編學(xué)習(xí)一下
    2022-02-02
  • Spring @Conditional注解講解及示例詳解

    Spring @Conditional注解講解及示例詳解

    這篇文章主要介紹了Spring @Conditional注解講解及示例詳解,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-12-12
  • 關(guān)于過濾器Filter的介紹和使用詳解

    關(guān)于過濾器Filter的介紹和使用詳解

    這篇文章主要介紹了關(guān)于過濾器Filter的使用,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2025-03-03
  • 淺談?dòng)肧pringBoot實(shí)現(xiàn)策略模式

    淺談?dòng)肧pringBoot實(shí)現(xiàn)策略模式

    本文主要介紹了SpringBoot實(shí)現(xiàn)策略模式,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-10-10
  • 詳解Mybatis的緩存

    詳解Mybatis的緩存

    這篇文章主要介紹了Mybatis緩存的相關(guān)資料,幫助大家更好的理解和使用Mybatis框架,感興趣的朋友可以了解下
    2021-01-01
  • JAVA根據(jù)ip地址獲取歸屬地的實(shí)現(xiàn)方法

    JAVA根據(jù)ip地址獲取歸屬地的實(shí)現(xiàn)方法

    本文主要介紹了JAVA根據(jù)ip地址獲取歸屬地的實(shí)現(xiàn)方法,要通過Java程序獲取IP地址對(duì)應(yīng)的城市,需要借助第三方的IP地址庫(kù),下面就來介紹一下,感興趣的可以了解一下
    2023-10-10
  • java實(shí)現(xiàn)訂餐系統(tǒng)

    java實(shí)現(xiàn)訂餐系統(tǒng)

    這篇文章主要為大家詳細(xì)介紹了java實(shí)現(xiàn)訂餐系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-07-07
  • java并發(fā)編程中實(shí)現(xiàn)可見性的四種可行方案解析

    java并發(fā)編程中實(shí)現(xiàn)可見性的四種可行方案解析

    這篇文章主要介紹了java并發(fā)編程中實(shí)現(xiàn)可見性的四種可行方案解析,使用關(guān)鍵字volatile和使用鎖(如synchronized關(guān)鍵字或者java.util.concurrent包中的鎖)來確保對(duì)共享變量的修改在多線程環(huán)境中能夠正確地被其他線程所觀察到,需要的朋友可以參考下
    2023-08-08
  • Mybatis千萬級(jí)數(shù)據(jù)查詢的解決方式,避免OOM問題

    Mybatis千萬級(jí)數(shù)據(jù)查詢的解決方式,避免OOM問題

    這篇文章主要介紹了Mybatis千萬級(jí)數(shù)據(jù)查詢的解決方式,避免OOM問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-01-01
  • 使用spring整合Quartz實(shí)現(xiàn)—定時(shí)器功能

    使用spring整合Quartz實(shí)現(xiàn)—定時(shí)器功能

    這篇文章主要介紹了使用spring整合Quartz實(shí)現(xiàn)—定時(shí)器功能,不基于特定的基類的方法,需要的朋友可以參考下
    2018-04-04

最新評(píng)論

松桃| 昭通市| 宣武区| 衡东县| 上高县| 荆州市| 桂平市| 云阳县| 蕲春县| 阳城县| 龙州县| 朝阳区| 衢州市| 西安市| 溧阳市| 古丈县| 大方县| 平遥县| 江阴市| 北流市| 珲春市| 泉州市| 贵州省| 五家渠市| 逊克县| 连平县| 岢岚县| 西安市| 堆龙德庆县| 温宿县| 临城县| 宁陕县| 满洲里市| 大宁县| 英吉沙县| 务川| 阿克苏市| 宜兰县| 康保县| 腾冲县| 内乡县|