国产精品电影_久久视频免费_欧美日韩国产激情_成年人视频免费在线播放_日本久久亚洲电影_久久都是精品_66av99_九色精品美女在线_蜜臀a∨国产成人精品_冲田杏梨av在线_欧美精品在线一区二区三区_麻豆mv在线看

一文搞懂設(shè)計模式—責(zé)任鏈模式

開發(fā) 前端
責(zé)任鏈模式通過將多個處理請求的對象組成一條鏈,使請求在鏈上傳遞,直到有一個對象處理它為止。每個處理對象都負(fù)責(zé)判斷自己能否處理該請求,如果可以則進(jìn)行處理,否則將請求傳遞給下一個處理對象。

責(zé)任鏈模式(Chain of Responsibility Pattern)是一種行為型設(shè)計模式,它允許多個對象按照順序處理請求,并且每個對象可以選擇自己是否處理該請求或?qū)⑵鋫鬟f給下一個對象。這種模式將請求的發(fā)送者和接收者解耦,同時提供了更大的靈活性和可擴(kuò)展性。

簡介

責(zé)任鏈模式通過將多個處理請求的對象組成一條鏈,使請求在鏈上傳遞,直到有一個對象處理它為止。每個處理對象都負(fù)責(zé)判斷自己能否處理該請求,如果可以則進(jìn)行處理,否則將請求傳遞給下一個處理對象。這樣,請求發(fā)送者無需知道具體的處理對象,只需將請求發(fā)送到責(zé)任鏈上即可。

責(zé)任鏈模式包含以下角色:

  • 抽象處理者(Handler):定義一個處理請求的接口,并持有下一個處理者的引用。
  • 具體處理者(Concrete Handler):實現(xiàn)抽象處理者的接口,在處理請求前判斷自己是否能夠處理該請求,如果可以則進(jìn)行處理,否則將請求傳遞給下一個處理者。

通過責(zé)任鏈模式,我們可以動態(tài)地組合處理對象,靈活地配置處理流程,這種解耦使得系統(tǒng)更加靈活和可擴(kuò)展。

使用場景

責(zé)任鏈模式常用于以下場景:

  • 動態(tài)組合處理流程:通過靈活配置責(zé)任鏈,可以動態(tài)地組合處理對象,實現(xiàn)不同的處理流程。每個處理者只需關(guān)注自己負(fù)責(zé)處理的請求,使得系統(tǒng)更加靈活和可擴(kuò)展。
  • 避免請求的發(fā)送者和接收者之間的直接耦合:通過將請求傳遞給責(zé)任鏈,請求發(fā)送者無需知道具體的處理對象,減少了對象之間的依賴關(guān)系。
  • 處理請求的順序可變:責(zé)任鏈模式允許在運(yùn)行時根據(jù)需要改變處理請求的順序,靈活調(diào)整處理流程。

常見的實際應(yīng)用場景包括:

  • 日志記錄器鏈:一個日志記錄系統(tǒng)可以根據(jù)日志級別將日志消息傳遞給不同的日志記錄器,如控制臺記錄器、文件記錄器、數(shù)據(jù)庫記錄器等。
  • 審批流程:一個多級審批系統(tǒng)可以根據(jù)審批者的權(quán)限和級別將審批請求傳遞給下一個級別的審批者,直到獲得最終的審批結(jié)果。
  • 異常處理:一個異常處理系統(tǒng)可以根據(jù)異常類型將異常進(jìn)行分類處理,如日志記錄、郵件通知、異常展示等。

責(zé)任鏈模式在這些場景中可以減少代碼的耦合性,提高代碼的可維護(hù)性和可擴(kuò)展性。

優(yōu)缺點

優(yōu)點:

  • 解耦發(fā)送者和接收者:責(zé)任鏈模式將請求的發(fā)送者和接收者解耦,發(fā)送者無需知道具體的處理對象,只需將請求發(fā)送到責(zé)任鏈上即可。
  • 靈活動態(tài)的處理流程:通過配置責(zé)任鏈,可以靈活地組合處理對象,實現(xiàn)不同的處理流程,并且可以在運(yùn)行時動態(tài)地改變處理的順序。
  • 增強(qiáng)代碼的可擴(kuò)展性:由于責(zé)任鏈模式遵循開閉原則,新的處理者可以隨時被加入到責(zé)任鏈中,不需要修改已有代碼,提供了良好的擴(kuò)展性。
  • 增強(qiáng)代碼的可維護(hù)性:每個處理者只需關(guān)注自己負(fù)責(zé)處理的請求,職責(zé)單一,使得代碼更加清晰、可讀性更高。

缺點:

  • 請求的處理不保證被處理:由于責(zé)任鏈中的每個處理者都可以選擇是否處理請求,如果沒有正確配置責(zé)任鏈或者某個處理者沒有正確處理請求,可能會導(dǎo)致請求無法被處理。
  • 性能問題:當(dāng)責(zé)任鏈過長或者請求在責(zé)任鏈中被頻繁傳遞時,可能會對性能產(chǎn)生影響。因此,在設(shè)計責(zé)任鏈時需要注意鏈的長度和處理的復(fù)雜度。
  • 調(diào)試不方便:當(dāng)責(zé)任鏈特別是鏈條比較長, 環(huán)節(jié)比較多的時候,由于采用了類似遞歸的方式,調(diào)試的時候邏輯可能比較復(fù)雜。

在實際應(yīng)用中,我們需要根據(jù)具體情況評估責(zé)任鏈模式的優(yōu)缺點,并合理地選擇使用或者改進(jìn)這個模式。

責(zé)任鏈模式實現(xiàn)

要實現(xiàn)責(zé)任鏈模式,我們按照以下步驟進(jìn)行:

  1. 定義處理者接口(Handler),聲明處理方法,并添加設(shè)置下一個處理者的方法。
  2. 實現(xiàn)具體處理者類(ConcreteHandler),實現(xiàn)處理方法,并在需要時選擇是否調(diào)用下一個處理者。
  3. 在客戶端代碼中創(chuàng)建責(zé)任鏈,并將請求發(fā)送到責(zé)任鏈上的第一個處理者。

以下是一個簡單的示例,演示如何使用責(zé)任鏈模式處理請假申請:

步驟一:定義處理者接口(Handler)

/**
 * <p>
 * 責(zé)任鏈模式——抽象類處理器
 * </p>
 */

public abstract class AbstractHandler {

    /**
     * 責(zé)任鏈中的下一個元素
     */
    protected AbstractHandler nextHandler;

    public AbstractHandler setNextChain(AbstractHandler nextHandler) {
        this.nextHandler = nextHandler;
        return nextHandler;
    }

    /**
     * 責(zé)任鏈處理邏輯
     */
    public void linkChain(LeaveRequest request) {
        handler(request);
        //這里還可以加入其他方法
        if (Objects.nonNull(nextHandler)) {
            nextHandler.linkChain(request);
        }
    }

    /**
     * 抽象方法
     */
    protected abstract void handler(LeaveRequest request);
}

請求對象為:

@Getter
public class LeaveRequest {
    private final String employee;
    private final int days;

    public LeaveRequest(String employee, int days) {
        this.employee = employee;
        this.days = days;
    }

}

步驟二:實現(xiàn)具體處理者類(ConcreteHandler)

@Slf4j
public class Handler1 extends AbstractHandler {

    @Override
    public void handler(LeaveRequest request) {
        if (request.getDays() <= 3) {
            log.info("ConcreteHandlerA 處理了 " + request.getEmployee() + " 的請假申請,天數(shù)為:" + request.getDays());
        }
    }
}

@Slf4j
public class Handler2 extends AbstractHandler {
    @Override
    public void handler(LeaveRequest request) {
        if (request.getDays() > 3 && request.getDays() <= 7) {
            log.info("ConcreteHandlerB 處理了 " + request.getEmployee() + " 的請假申請,天數(shù)為:" + request.getDays());
        }
    }
}

@Slf4j
public class Handler3 extends AbstractHandler {
    @Override
    protected void handler(LeaveRequest request) {
        if (request.getDays() > 7) {
            log.info("ConcreteHandlerC 處理了 " + request.getEmployee() + " 的請假申請,天數(shù)為:" + request.getDays());
        }
    }
}

步驟三:在客戶端代碼中創(chuàng)建責(zé)任鏈,并將請求發(fā)送到責(zé)任鏈上的第一個處理者

public class ChainPatternDemo {
    private static AbstractHandler getChainOfHandler() {
        AbstractHandler handler1 = new Handler1();
        AbstractHandler handler2 = new Handler2();
        AbstractHandler handler3 = new Handler3();
        //可以自定義鏈路順序
        handler1.setNextChain(handler2).setNextChain(handler3);
        return handler1;
    }

    public static void main(String[] args) {
        AbstractHandler chain = getChainOfHandler();
        LeaveRequest request1 = new LeaveRequest("張三", 2);
        chain.linkChain(request1);

        LeaveRequest request2 = new LeaveRequest("李四", 5);
        chain.linkChain(request2);

        LeaveRequest request3 = new LeaveRequest("王五", 10);
        chain.linkChain(request3);
    }
}

在上述示例中,我們定義了三個具體處理者類:Handler1、Handler2和Handler3,它們分別處理請假申請。客戶端代碼創(chuàng)建了責(zé)任鏈,并將請求發(fā)送給第一個處理者Handler1。每個具體處理者判斷自己是否能夠處理該請求,如果可以則進(jìn)行處理,否則傳遞給下一個處理者。

運(yùn)行以上代碼,輸出結(jié)果為:

ConcreteHandlerA 處理了 張三 的請假申請,天數(shù)為:2
ConcreteHandlerB 處理了 李四 的請假申請,天數(shù)為:5
ConcreteHandlerC 處理了 王五 的請假申請,天數(shù)為:10

這只是一個簡單示例,實際使用時可以根據(jù)業(yè)務(wù)需求進(jìn)行適當(dāng)?shù)臄U(kuò)展和修改。

在使用責(zé)任鏈模式時,需要注意以下幾點:

  • 確定責(zé)任鏈中的處理順序:要確保責(zé)任鏈中處理者的順序是正確的,以便能夠按照預(yù)期處理請求。處理者的順序可以在創(chuàng)建責(zé)任鏈時進(jìn)行設(shè)置。
  • 避免出現(xiàn)循環(huán)引用:如果責(zé)任鏈中的處理者之間出現(xiàn)了循環(huán)引用,可能會導(dǎo)致請求無法被正確處理或進(jìn)入死循環(huán)。因此,在設(shè)置下一個處理者時要注意避免出現(xiàn)循環(huán)引用的情況。
  • 處理者的數(shù)量控制:在設(shè)計責(zé)任鏈時要注意控制處理者的數(shù)量,避免責(zé)任鏈過長導(dǎo)致性能下降。可以根據(jù)實際需求合理劃分責(zé)任鏈,將相關(guān)的處理邏輯放在同一個處理者中,可以在 Handler 中設(shè)置一個最大節(jié)點數(shù)量,在 setNextChain() 方法中判斷是否已經(jīng)是超過其閾值,超過則不允許該鏈建立,避免無意識地破壞系統(tǒng)性能。

通過建造者模式優(yōu)化

我們可以通過建造者模式來創(chuàng)建責(zé)任鏈中的處理者對象。這種優(yōu)化可以使責(zé)任鏈的創(chuàng)建和配置更加靈活和可拓展,符合開閉原則。

優(yōu)化后的示例代碼:

/**
 * <p>
 * 責(zé)任鏈模式——抽象類處理器
 * </p>
 */

public abstract class AbstractHandler {

    /**
     * 責(zé)任鏈中的下一個元素
     */
    protected AbstractHandler nextHandler;

    private void setNextChain(AbstractHandler nextHandler) {
        this.nextHandler = nextHandler;
    }

    /**
     * 責(zé)任鏈處理邏輯
     */
    public void linkChain(LeaveRequest request) {
        handler(request);
        //這里還可以加入其他方法
        if (Objects.nonNull(nextHandler)) {
            nextHandler.linkChain(request);
        }
    }

    /**
     * 抽象方法
     */
    protected abstract void handler(LeaveRequest request);

    public static class Builder {
        private AbstractHandler head;
        private AbstractHandler tail;

        public Builder addHandler(AbstractHandler handler) {
            if (this.head == null) {
                this.head = this.tail = handler;
                return this;
            }
            this.tail.setNextChain(handler);
            this.tail = handler;
            return this;
        }

        public AbstractHandler build() {
            return this.head;
        }
    }
}
public class ChainPatternDemo {
    private static AbstractHandler getChainOfHandler() {
        return new AbstractHandler.Builder()
                .addHandler(new Handler1())
                .addHandler(new Handler2())
                .addHandler(new Handler3())
                .build();
    }

    public static void main(String[] args) {
        AbstractHandler chain = getChainOfHandler();
        LeaveRequest request1 = new LeaveRequest("張三", 2);
        chain.linkChain(request1);

        LeaveRequest request2 = new LeaveRequest("李四", 5);
        chain.linkChain(request2);

        LeaveRequest request3 = new LeaveRequest("王五", 10);
        chain.linkChain(request3);
    }
}

在客戶端代碼中,我們使用建造者模式創(chuàng)建了一個包含多個處理者的責(zé)任鏈,并發(fā)送了一個請假申請。責(zé)任鏈會按照添加處理者的順序依次處理請假申請,直到找到能夠處理該請求的處理者為止。

通過調(diào)用 addHandler 方法,我們可以逐步構(gòu)建責(zé)任鏈,將處理者添加到責(zé)任鏈的末尾,由于 setNextChain()  不對外調(diào)用,作用域可以更改為 private,最后,通過調(diào)用 build 方法,我們可以獲取責(zé)任鏈的起始處理者。

Spring中使用責(zé)任鏈模式

Spring中我們可以使用 @Component,@Order 注解,來讓容器幫我們自動構(gòu)建責(zé)任鏈,從而簡化代碼。

public abstract class Handler {
    abstract void handler(LeaveRequest request);
}
@Order(value = 1)
@Component
@Slf4j
public class HandlerA extends Handler{
    @Override
    public void handler(LeaveRequest request) {
        if (request.getDays() <= 3) {
            log.info("ConcreteHandlerA 處理了 " + request.getEmployee() + " 的請假申請,天數(shù)為:" + request.getDays());
        }
    }
}

@Order(value = 2)
@Component
@Slf4j
public class HandlerB extends Handler {
    @Override
    public void handler(LeaveRequest request) {
        if (request.getDays() > 3 && request.getDays() <= 7) {
            log.info("ConcreteHandlerB 處理了 " + request.getEmployee() + " 的請假申請,天數(shù)為:" + request.getDays());
        }
    }
}

@Order(value = 3)
@Component
@Slf4j
public class HandlerC extends Handler{
    @Override
    public void handler(LeaveRequest request) {
        if (request.getDays() > 7) {
            log.info("ConcreteHandlerC 處理了 " + request.getEmployee() + " 的請假申請,天數(shù)為:" + request.getDays());
        }
    }
}

測試:

@Test
public void test() {
        for (Handler handler : handlerChain) {
            LeaveRequest request =  new LeaveRequest("王五", 10);
            handler.handler(request);
        }
    }

輸出:

ConcreteHandlerC 處理了 王五 的請假申請,天數(shù)為:10

這種寫法有其利弊,優(yōu)點是可以避免繁瑣的責(zé)任鏈構(gòu)建過程,簡化了代碼結(jié)構(gòu);缺點是具體處理者類之間的執(zhí)行順序不夠直觀,具體使用時需要權(quán)衡考慮。

責(zé)任鏈模式的優(yōu)點在于其低耦合性、靈活性和可擴(kuò)展性,使得我們能夠更加輕松地管理和組織復(fù)雜的處理流程。然而,也要注意其缺點,即請求未必被處理和對處理順序敏感的特點。

最重要的是,在實際應(yīng)用中根據(jù)具體需求合理運(yùn)用責(zé)任鏈模式,結(jié)合其他設(shè)計模式,以便在代碼結(jié)構(gòu)和可維護(hù)性上取得更好的效果。

責(zé)任編輯:武曉燕 來源: Java隨想錄
相關(guān)推薦

2024-02-26 11:52:38

代理模式設(shè)計

2024-01-29 12:22:07

設(shè)計模式策略模式

2024-02-19 13:11:38

門面模式系統(tǒng)

2020-11-17 09:32:57

設(shè)計模式責(zé)任鏈

2023-05-22 13:27:17

2024-02-21 12:24:33

模板設(shè)計模式框架

2024-02-23 12:11:53

裝飾器模式對象

2024-02-27 11:59:12

享元模式對象

2024-02-04 12:04:17

2024-02-22 12:13:49

適配器模式代碼

2024-02-18 12:36:09

2024-02-20 12:09:32

模式工廠方法接口

2021-12-24 07:50:45

責(zé)任鏈模式設(shè)計

2012-03-28 13:28:56

Java設(shè)計模式

2022-05-05 16:47:24

Docker網(wǎng)絡(luò)空間容器

2010-04-01 09:10:03

PHP設(shè)計模式責(zé)任鏈模式

2022-11-01 08:46:20

責(zé)任鏈模式對象

2023-06-05 07:55:31

2022-09-21 16:56:16

設(shè)計模式微服務(wù)架構(gòu)

2023-09-26 00:27:07

設(shè)計模式鏈接
點贊
收藏

51CTO技術(shù)棧公眾號

av片中文字幕| 芒果视频成人app| 日韩一级欧洲| 欧美变态tickle挠乳网站| 色婷婷综合网站| 快she精品国产999| 秋霞午夜一区二区| 亚洲第一影院| 欧美日韩国产a| 四虎国产精品成人免费4hu| 久久中文欧美| 国产精品无av码在线观看| 欧美www.| 777a∨成人精品桃花网| 激情六月婷婷| 91天堂素人约啪| 亚洲开发第一视频在线播放| 欧美黄色录像片| 美日韩在线视频| 忘忧草在线影院两性视频| 日本韩国欧美在线| 国产黄色片大全| 99视频精品全部免费在线| 日本不卡久久| 欧美一区高清| 国产精品v日韩精品| 先锋影音一区二区| 日韩成人在线观看| av在线网址观看| 欧美视频完全免费看| 亚欧精品一区| 亚洲天堂网中文字| 中国黄色片免费看| 91视频xxxx| 欧美视频免费看欧美视频| 日韩专区中文字幕一区二区| 国产98在线|日韩| 永久91嫩草亚洲精品人人| 性色av一区二区三区免费| 久久国产三级| 久久精品国产一区| 国产福利一区二区三区在线播放| 日韩激情视频在线| 欧美gv在线观看| 亚洲精品国产suv| 国产精品蜜臀| 日韩精品最新网址| 久久香蕉av| 欧美精品一区二区三| 在线中文字幕电影| 91麻豆精品久久久久蜜臀| 三区四区电影在线观看| 欧美伊人久久大香线蕉综合69| 蜜桃视频在线免费| 欧美日韩国产片| 国产理论电影在线| 亚洲日韩中文字幕在线播放| 亚洲性受xxx喷奶水| 在线视频欧美性高潮| 96视频在线观看欧美| 97精品一区二区三区| 欧美人与物videos另类xxxxx| 国产精品福利观看| 亚洲精品国产首次亮相| 国产一区二区中文字幕免费看| 一本色道精品久久一区二区三区| 精品国产乱码久久久久久久软件| 一区二区三区福利| 伊人久久大香线蕉成人综合网| 成人午夜精品一区二区三区| 亚洲乱码日产精品bd在线观看| 97se亚洲国产综合自在线观| 在线观看国产一级片| 五月婷婷欧美视频| 精品国产丝袜高跟鞋| 亚洲精品在线91| 亚洲综合影院| 成人在线精品视频| 亚洲在线免费| 国产爆乳无码一区二区麻豆| 国产欧美日韩另类视频免费观看| 黄页网站在线观看| 91麻豆精品国产91久久久久| 国产精品亚洲一区二区三区在线观看| 欧美成人免费一级人片100| 国内成人自拍| 日韩av在线一区二区三区| 99免费精品在线观看| 一二三四社区在线视频| 欧美片在线播放| 亚洲欧洲日韩精品在线| 国产一区在线播放| 日韩影院免费视频| 日本成人中文字幕在线| 色综合咪咪久久| 奇米777日韩| 国产精品成人一区| 蜜臀久久久99精品久久久久久| 狠狠热免费视频| 欧美图片一区二区三区| 天然素人一区二区视频| 国产精品免费一区二区三区都可以 | 亚洲图片欧美综合| 精产国品自在线www| 久久亚洲国产成人| 国产精品草草| av之家在线观看| 疯狂做受xxxx欧美肥白少妇 | 日韩中文字幕精品视频| 成人女性视频| 先锋影音男人资源| 五月天亚洲精品| 亚洲四虎影院| 国产综合第一页| 99精品美女| 你真棒插曲来救救我在线观看| 欧美日韩国产影院| 国产精品一区二区三区四区在线观看 | 自拍偷拍一区二区三区四区| 欧美三级在线看| 日韩成人视屏| 天堂资源在线亚洲资源| 一区二区三区视频在线看| 中文字幕在线看片| 91免费国产网站| 久久婷婷综合激情| 成人黄色在线电影| 日本一区二区在线播放| 成人免费看视频| 青春草在线视频| 国产精品专区第二| 久久综合色播五月| 国产美女高潮在线观看| 国产二区一区| 综合亚洲深深色噜噜狠狠网站| 校园春色亚洲色图| 日本免费高清一区| 欧美中文字幕一区二区三区亚洲 | 快播亚洲色图| 亚洲色图欧美在线| 国产日韩欧美中文在线| 中文字幕在线亚洲精品| 欧美三级中文字幕| 国产精品毛片久久| |精品福利一区二区三区| 91社在线播放| 欧美日韩三级一区| 久久久久国产精品| 国产伦精品一区二区三区视频黑人| 亚洲色大成网站www久久九九| 福利一区在线| 国产精品美女黄网| 婷婷六月综合亚洲| 日韩福利视频一区| www.日本一区| 精品中文字幕在线| 91在线视频播放地址| 91看片一区| 中文字幕无码精品亚洲资源网久久| 亚洲加勒比久久88色综合| 视频在线观看一区| av毛片在线看| 日产精品一线二线三线芒果| 日韩天堂在线观看| 日本免费新一区视频| 懂色av一区| 亚洲欧洲精品一区| 日韩精品视频在线观看网址| 老色鬼精品视频在线观看播放| 91黄页在线观看| 国产情侣第一页| 在线视频一区二区| 91片在线免费观看| www.欧美视频| 国产三区在线视频| 亚洲3p在线观看| 亚洲免费观看高清完整版在线 | 久久综合毛片| 日韩久久免费av| 国产成人自拍网| 亚洲网一区二区三区| 黄色漫画在线免费观看| 国产专区欧美专区| 欧美日韩亚洲综合在线 | 精品视频在线播放| 不卡一区在线观看| 亚洲1区在线| 一级特黄视频| 精品免费二区三区三区高中清不卡| 亚洲成av人影院在线观看| 成人美女视频在线看| 亚洲电影男人天堂| av大片在线观看| 欧美一级中文字幕| 2020久久国产精品| 五月天中文字幕一区二区| 亚洲天堂成人| 91tv亚洲精品香蕉国产一区| 黄色永久免费网站| 国产精品精品久久久久久|