成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

設(shè)計(jì)模式之不一樣的責(zé)任鏈模式

開發(fā) 前端
責(zé)任鏈模式適用于存在多個(gè)處理步驟、每個(gè)處理步驟具有獨(dú)立邏輯或條件、需要靈活組合和擴(kuò)展的場景。通過責(zé)任鏈模式,可以將復(fù)雜的處理邏輯拆分為多個(gè)獨(dú)立的處理步驟,并且可以動(dòng)態(tài)地組合和調(diào)整處理步驟的順序,從而提高系統(tǒng)的靈活性和可維護(hù)性。希望本文能夠幫助讀者理解和應(yīng)用責(zé)任鏈模式,提升軟件設(shè)計(jì)和開發(fā)的能力。

責(zé)任鏈模式(Chain of Responsibility Pattern)是一種行為型設(shè)計(jì)模式,它通過將請求的發(fā)送者和接收者解耦,使多個(gè)對象都有機(jī)會(huì)處理請求。在這個(gè)模式中,請求沿著一個(gè)處理鏈依次傳遞,直到有一個(gè)對象能夠處理它為止。

本文將詳細(xì)介紹責(zé)任鏈模式的概述、應(yīng)用場景以及代碼示例,來幫助讀者更好地理解和應(yīng)用這個(gè)模式。

1. 簡介

模式概述

責(zé)任鏈模式的核心思想是將請求的發(fā)送者和接收者解耦,使得多個(gè)對象都有機(jī)會(huì)處理請求。在責(zé)任鏈模式中,請求會(huì)沿著一個(gè)處理鏈依次傳遞,每個(gè)處理者都有機(jī)會(huì)處理請求,如果一個(gè)處理者不能處理請求,則將請求傳遞給下一個(gè)處理者,直到有一個(gè)處理者能夠處理它。

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

圖片

責(zé)任鏈模式類結(jié)構(gòu)

  • 抽象處理者(Handler):定義了處理請求的接口,通常包含一個(gè)指向下一個(gè)處理者的引用,用于將請求傳遞給下一個(gè)處理者。
  • 具體處理者(ConcreteHandler):實(shí)現(xiàn)了處理請求的接口,具體處理者可以決定是否處理請求,如果不能處理,則將請求傳遞給下一個(gè)處理者。
  • 客戶端(Client):創(chuàng)建處理者對象并組成責(zé)任鏈的結(jié)構(gòu),負(fù)責(zé)將請求發(fā)送給第一個(gè)處理者。

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

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

  • 責(zé)任鏈模式可以實(shí)現(xiàn)請求的發(fā)送者和接收者之間的解耦。發(fā)送者只需要將請求發(fā)送給第一個(gè)處理者,無需關(guān)心具體是哪個(gè)處理者來處理。這樣,系統(tǒng)的靈活性大大增強(qiáng),可以隨時(shí)增加或修改處理者的順序。
  • 責(zé)任鏈模式能夠避免請求的發(fā)送者和接收者之間的緊耦合。每個(gè)處理者只需要關(guān)心自己負(fù)責(zé)的請求類型,無需關(guān)心其他請求。這樣,系統(tǒng)的可維護(hù)性也得到了提升。
  • 責(zé)任鏈模式可以靈活地動(dòng)態(tài)添加或刪除處理者。我們可以根據(jù)實(shí)際情況來調(diào)整責(zé)任鏈的結(jié)構(gòu),以滿足不同的業(yè)務(wù)需求。

缺點(diǎn):

  • 復(fù)雜度會(huì)明顯提升,如果責(zé)任鏈過長或者處理者之間的關(guān)系復(fù)雜,可能還會(huì)導(dǎo)致性能下降和調(diào)試?yán)щy。

應(yīng)用場景

責(zé)任鏈模式在許多不同的應(yīng)用場景中都有廣泛的應(yīng)用。下面列舉了一些常見的應(yīng)用場景:

  • 請求處理鏈:當(dāng)一個(gè)請求需要經(jīng)過多個(gè)處理步驟或處理者進(jìn)行處理時(shí),可以使用責(zé)任鏈模式。每個(gè)處理者負(fù)責(zé)一部分邏輯,處理完后可以選擇將請求傳遞給下一個(gè)處理者,從而形成一個(gè)處理鏈。
  • 日志記錄:在日志系統(tǒng)中,可以使用責(zé)任鏈模式來記錄日志。不同的處理者可以負(fù)責(zé)不同級別的日志記錄,例如,一個(gè)處理者負(fù)責(zé)記錄錯(cuò)誤日志,另一個(gè)處理者負(fù)責(zé)記錄調(diào)試日志,然后按照鏈?zhǔn)浇Y(jié)構(gòu)傳遞日志。
  • 身份驗(yàn)證和權(quán)限檢查:在身份驗(yàn)證和權(quán)限檢查系統(tǒng)中,可以使用責(zé)任鏈模式來驗(yàn)證用戶的身份和權(quán)限。每個(gè)處理者可以檢查特定的條件,例如用戶名和密碼的正確性、賬戶是否鎖定等。如果一個(gè)處理者無法通過驗(yàn)證,可以將請求傳遞給下一個(gè)處理者。
  • 數(shù)據(jù)過濾和轉(zhuǎn)換:在數(shù)據(jù)處理過程中,可以使用責(zé)任鏈模式來進(jìn)行數(shù)據(jù)過濾和轉(zhuǎn)換。每個(gè)處理者可以根據(jù)特定的條件過濾數(shù)據(jù)或?qū)?shù)據(jù)進(jìn)行轉(zhuǎn)換,然后將處理后的數(shù)據(jù)傳遞給下一個(gè)處理者。
  • 錯(cuò)誤處理和異常處理:在錯(cuò)誤處理和異常處理系統(tǒng)中,可以使用責(zé)任鏈模式來處理錯(cuò)誤和異常。不同的處理者可以處理不同類型的錯(cuò)誤或異常,并根據(jù)需要將錯(cuò)誤或異常傳遞給下一個(gè)處理者進(jìn)行進(jìn)一步處理或記錄。

2. Java 代碼示例

在 Java 中實(shí)現(xiàn)責(zé)任鏈模式有多種方式,包括基于接口、基于抽象類、基于注解等。下面將詳細(xì)介紹基于接口的常見實(shí)現(xiàn)方式。

基于接口的實(shí)現(xiàn)方式是通過定義一個(gè)處理請求的接口,每個(gè)處理者實(shí)現(xiàn)這個(gè)接口,并在自己的實(shí)現(xiàn)中決定是否處理請求和傳遞請求給下一個(gè)處理者。

首先,我們定義一個(gè)處理請求的接口 Handler 以及請求入?yún)?nbsp;Request:

public interface Handler {
    void handleRequest(Request request);
}

public class Request {
    private String type;
    // 省略getter、setter
}

然后,我們創(chuàng)建3個(gè)具體的處理者類實(shí)現(xiàn)這個(gè)接口,在具體處理者類的實(shí)現(xiàn)中,首先判斷自己是否能夠處理請求,如果能夠處理,則進(jìn)行處理;否則將請求傳遞給下一個(gè)處理者。代碼如下:

public class ConcreteHandlerA implements Handler {
    private Handler successor;

    public void setSuccessor(Handler successor) {
        this.successor = successor;
    }

    public void handleRequest(Request request) {
        if (request.getType().equals("A")) {
            // 處理請求的邏輯
        } else if (successor != null) {
            successor.handleRequest(request);
        }
    }
}

public class ConcreteHandlerB implements Handler {
    private Handler successor;

    public void setSuccessor(Handler successor) {
        this.successor = successor;
    }

    public void handleRequest(Request request) {
        if (request.getType().equals("B")) {
            // 處理請求的邏輯
        } else if (successor != null) {
            successor.handleRequest(request);
        }
    }
}

public class ConcreteHandlerC implements Handler {
    private Handler successor;

    public void setSuccessor(Handler successor) {
        this.successor = successor;
    }

    public void handleRequest(Request request) {
        if (request.getType().equals("C")) {
            // 處理請求的邏輯
        } else if (successor != null) {
            successor.handleRequest(request);
        }
    }
}

接下來,我們創(chuàng)建一個(gè)客戶端類 Client,用于創(chuàng)建處理者對象并組成責(zé)任鏈的結(jié)構(gòu):

public class Client {
    public static void main(String[] args) {
        Handler handlerA = new ConcreteHandlerA();
        Handler handlerB = new ConcreteHandlerB();
        Handler handlerC = new ConcreteHandlerC();

        handlerA.setSuccessor(handlerB);
        handlerB.setSuccessor(handlerC);

        // 創(chuàng)建請求并發(fā)送給第一個(gè)處理者
        Request request = new Request("A");
        handlerA.handleRequest(request);
    }
}

在客戶端類中,我們創(chuàng)建了具體的處理者對象,并通過 setSuccessor() 方法將它們組成一個(gè)責(zé)任鏈的結(jié)構(gòu)。然后,創(chuàng)建一個(gè)請求對象,并將請求發(fā)送給第一個(gè)處理者。

基于接口的實(shí)現(xiàn)方式簡單直觀,每個(gè)處理者只需要實(shí)現(xiàn)一個(gè)接口即可。但是它的缺點(diǎn)是如果責(zé)任鏈較長,需要?jiǎng)?chuàng)建多個(gè)處理者對象,增加了系統(tǒng)的復(fù)雜性和資源消耗。下面基于 Spring 框架實(shí)現(xiàn)一個(gè)高級版的責(zé)任鏈模式。

3. Spring 代碼示例

在實(shí)際開發(fā)中,一個(gè)請求會(huì)在多個(gè)處理器之間流轉(zhuǎn),每個(gè)處理器都可以處理請求。

假設(shè)我們有一個(gè) Spring 框架開發(fā)的訂單處理系統(tǒng),訂單需要依次經(jīng)過訂單檢查、庫存處理、支付處理。如果某個(gè)處理環(huán)節(jié)無法處理訂單,將會(huì)終止處理并返回錯(cuò)誤信息,只有每個(gè)處理器都完成了請求處理,這個(gè)訂單才算法下單成功。

首先,我們定義一個(gè)訂單類 Order:

@Data
@AllArgsConstructor
public class orderNo {
    private String orderNumber;
    private String paymentMethod;
    private boolean stockAvailability;
    private String shippingAddress;
}

然后,我們定義一個(gè)抽象訂單處理者類 OrderHandler:

public abstract class OrderHandler {
    public abstract void handleOrder(Order order);
}

接下來,我們創(chuàng)建具體的訂單處理者類繼承自抽象訂單處理者類,實(shí)現(xiàn)相應(yīng)的方法,并注冊到 Spring 中,

@Component
public class CheckOrderHandler extends OrderHandler {
    public void handleOrder(Order order) {
        if (StringUtils.isBlank(order.getOrderNo())) {
            throw new RuntimeException("訂單編號不能為空");
        }
        if (order.getPrice().compareTo(BigDecimal.ONE) <= 0) {
            throw new RuntimeException("訂單金額不能小于等于0");
        }
        if (StringUtils.isBlank(order.getShippingAddress())) {
            throw new RuntimeException("收貨地址不能為空");
        }
        System.out.println("訂單參數(shù)檢驗(yàn)通過");
    }
}

@Component
public class StockHandler extends OrderHandler {
    public void handleOrder(Order order) {
        if (!order.isStockAvailability()) {
            throw new RuntimeException("訂單庫存不足");
        }
        System.out.println("庫存扣減成功");
    }
}

@Component
public class AliPaymentHandler extends OrderHandler {
    public void handleOrder(Order order) {
        if (!order.getPaymentMethod().equals("支付寶")) {
            throw new RuntimeException("不支持支付寶以外的支付方式");
        }
        System.out.println("支付寶預(yù)下單成功");
    }
}

在具體訂單處理者類的實(shí)現(xiàn)中,CheckOrderHandler 負(fù)責(zé)做訂單參數(shù)檢查、StockHandler 負(fù)責(zé)做庫存扣減、AliPaymentHandler 負(fù)責(zé)做預(yù)下單,每個(gè)處理者的邏輯都是相互獨(dú)立各不不干擾。

最后,我們創(chuàng)建一個(gè)訂單生產(chǎn)鏈條 BuildOrderChain ,用于組成責(zé)任鏈的鏈條處理結(jié)構(gòu):

@Component
public class BuildOrderChain {

    @Autowired
    private AliPaymentHandler aliPaymentHandler;

    @Autowired
    private CheckOrderHandler checkOrderHandler;

    @Autowired
    private StockHandler stockHandler;

    List<OrderHandler> list = new ArrayList<>();

    @PostConstruct
    public void init() {
        // 1. 檢查訂單參數(shù)
        list.add(checkOrderHandler);
        // 2. 扣減庫存
        list.add(stockHandler);
        // 3. 支付寶預(yù)下單
        list.add(aliPaymentHandler);
    }

    public void doFilter(Order order) {
        for (OrderHandler orderHandler : this.list) {
            orderHandler.handleOrder(order);
        }
    }
}

訂單生產(chǎn)鏈條 BuildOrderChain 類中,我們通過 @PostConstruct 注解下的 init() 初始化方法,將具體的訂單處理者按代碼順序組成一個(gè)責(zé)任鏈的結(jié)構(gòu)。然后通過 doFilter(order) 方法遍歷處理者集合依次處理。

運(yùn)行代碼,

@Slf4j
@SpringBootTest
@RunWith(SpringRunner.class)
public class OrderChainTest {
    @Autowired
    private BuildOrderChain buildOrderChain;

    @Test
    public void test() {
        Order order = new Order("123456", "支付寶",
                      true, "長沙", new BigDecimal("100"));
        buildOrderChain.doFilter(order);
    }

}

-------------------------------
訂單參數(shù)檢驗(yàn)通過
庫存扣減成功
支付寶預(yù)下單成功

可以看到訂單依次經(jīng)過校驗(yàn)處理器、庫存處理器和支付處理器進(jìn)行處理,直到最后完成整個(gè)訂單的處理。

在舉個(gè)例子,假如我們的訂單針對的是虛擬不限庫存商品,我們不需要進(jìn)行庫存扣減,那我們可以直接新建 VirtualGoodsOrderChain 虛擬商品訂單生產(chǎn)鏈條類,代碼如下,

@Component
public class VirtualGoodsOrderChain {
    @Autowired
    private AliPaymentHandler aliPaymentHandler;

    @Autowired
    private CheckOrderHandler checkOrderHandler;

    List<OrderHandler> list = new ArrayList<>();

    @PostConstruct
    public void init() {
        // 1. 檢查訂單參數(shù)
        list.add(checkOrderHandler);
        // 2 支付寶預(yù)下單
        list.add(aliPaymentHandler);
    }

    public void doFilter(Order order) {
        for (OrderHandler orderHandler : this.list) {
            orderHandler.handleOrder(order);
        }
    }
}

運(yùn)行代碼:

@Test
public void virtualOrderTest() {
    Order order = new Order("123456", "支付寶", true, "長沙", new BigDecimal("100"));
    virtualGoodsOrderChain.doFilter(order);
}

-------------------------------------------
訂單參數(shù)檢驗(yàn)通過
支付寶預(yù)下單成功

4. 總結(jié)

總的來說,責(zé)任鏈模式適用于存在多個(gè)處理步驟、每個(gè)處理步驟具有獨(dú)立邏輯或條件、需要靈活組合和擴(kuò)展的場景。通過責(zé)任鏈模式,可以將復(fù)雜的處理邏輯拆分為多個(gè)獨(dú)立的處理步驟,并且可以動(dòng)態(tài)地組合和調(diào)整處理步驟的順序,從而提高系統(tǒng)的靈活性和可維護(hù)性。希望本文能夠幫助讀者理解和應(yīng)用責(zé)任鏈模式,提升軟件設(shè)計(jì)和開發(fā)的能力。

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

2021-09-07 10:44:35

異步單例模式

2021-12-24 07:50:45

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

2010-04-01 09:10:03

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

2012-03-07 17:24:10

戴爾咨詢

2012-12-20 10:17:32

IT運(yùn)維

2024-01-30 13:15:00

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

2012-03-28 13:28:56

Java設(shè)計(jì)模式

2020-11-17 09:32:57

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

2017-05-25 15:02:46

聯(lián)宇益通SD-WAN

2016-05-09 18:40:26

VIP客戶緝拿

2015-10-19 12:33:01

華三/新IT

2018-05-09 15:42:24

新零售

2009-02-04 15:43:45

敏捷開發(fā)PHPFleaPHP

2009-12-01 16:42:27

Gentoo Linu

2011-02-28 10:38:13

Windows 8

2009-06-12 15:26:02

2016-03-24 18:51:40

2022-11-01 08:46:20

責(zé)任鏈模式對象

2023-09-26 00:27:07

設(shè)計(jì)模式鏈接

2015-08-04 14:49:54

Discover
點(diǎn)贊
收藏

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

主站蜘蛛池模板: 国产探花在线观看视频 | 草久在线 | 一区二区视频 | 免费一看一级毛片 | 国产午夜视频 | 国产一级视频免费播放 | 国产 日韩 欧美 在线 | 一区二区三区视频在线免费观看 | 国产午夜精品一区二区三区嫩草 | 亚洲传媒在线 | 人人鲁人人莫人人爱精品 | 狠狠躁躁夜夜躁波多野结依 | 在线成人免费视频 | 四虎成人av| 国产一二区在线 | yeyeav| 亚洲免费成人 | 午夜免费福利电影 | 日韩av在线中文字幕 | 久久99精品久久久 | 天天综合操 | 91精品国产91久久久久久最新 | 国产精品一级在线观看 | 国产亚洲一区二区三区在线 | 精品一区二区免费视频 | 日韩精品欧美精品 | 国产精品久久在线 | 五月婷婷激情 | 成人免费毛片在线观看 | 成人午夜黄色 | 成人综合一区 | 亚洲视频中文字幕 | 成人国产精品免费观看视频 | 欧美成人一区二区三区 | 99久久婷婷国产综合精品电影 | 在线播放亚洲 | 久久久久国产精品 | 国产精品一区二区av | www97影院 | 欧美精品一二区 | 午夜视频免费网站 |