責任鏈模式之在項目中應用
這篇記錄是今天突然看到別人寫的責任鏈模式文章的時候想起來我在項目中如何應用責任鏈模式的,因此隨手記錄下,希望生活更美好。
1、簡介
責任鏈模式在我們工作中經常接觸到的算是Java web中的filter了,每一個HttpRequest都會流經每個filter,在每個filter中對request做感興趣的事。結構就類似下面這張圖。
2責任鏈模式標準示例
責任鏈模式一般由一個抽象類和多個具體實現類組成,示例圖如下。
- 抽象基類Processor :這個類作爲一個基類,其中組合了一個和自己類型一樣的屬性變量用來代表下一個處理者。
- 具體實現類ProcessorA : 這個類是Processor的具體實現類,對感興趣請求做處理。
代碼演示如下:
① 定義抽象基類
public abstract class Processor {
Processor processor;
public Processor getProcessor() {
return processor;
}
public void setProcessor(Processor processor) {
this.processor = processor;
}
public abstract Object Process(Object request);
}
② 定義具體實現類
// 具體實現類1
public class ProcessorA extends Processor {
@Override
public Object process(Object request) {
if(request.equals("fuhang")){
System.out.println("ProcessorA request process");
}else{
System.out.println("ProcessorA request can not process");
if(processor != null){
processor.process(request);
}
}
return null;
}
}
// 具體實現類2
public class ProcessorB extends Processor {
@Override
public Object process(Object request) {
if(request.equals("fuhang")){
System.out.println("ProcessorB request process");
}else{
System.out.println("ProcessorB request can not process");
if(processor != null){
processor.process(request);
}
}
return null;
}
}
③ 測試類
public class ProcessorTest {
Processor processor;
public Processor getProcessor() {
return processor;
}
public void setProcessor(Processor processor) {
this.processor = processor;
}
public static void main(String[] args) {
// 模擬業務類
ProcessorTest processorTest = new ProcessorTest();
// 手動創建責任鏈
ProcessorA processorA = new ProcessorA();
ProcessorB processorB = new ProcessorB();
processorA.setProcessor(processorB);
processorTest.setProcessor(processorA);
// 測試
processorTest.getProcessor().process("fuhang");
processorTest.getProcessor().process("zhangsan");
}
}
// 輸出
//ProcessorA request process
//ProcessorA request can not process
//ProcessorB request can not process
小結
以上就是一個純責任鏈模式的示例程序,從主業務類接收到請求一路向下傳遞處理,若責任鏈上某個處理者可以處理請求則結束。
實際開發中大部分使用的是非純責任鏈模式,即責任鏈中每個節點處理完請求後還會繼續向下傳遞,一直到責任鏈結束,猶如流水線,畫個圖方便理解。
3、我在項目中的應用
我是一名Java開發者,但是日常工作是和區塊鏈系統打交道,目前具體來說是和以太坊區塊鏈客戶端打交道。
我們有一個需求是監聽我們自己智能合約上發生的任何事件,這些事件包括代幣轉賬、黑名單操作、合約擁有者轉移、鑄幣、銷燬代幣、暫停合約、管理員變更等等事件。在程序中我們需要監聽我們自己的智能合約在以太坊公鏈上發出的事件,事件格式是統一的,當監聽到事件時候根據具體事件進行相應處理,有可能需要一個處理器操作,有可能需要多個處理器操作。
從上面的描述我第一印象是工廠的流水線。隨後就想設計模式中有沒有適用的,最後責任鏈模式適配我們的需求就再合適不過了。使用責任鏈模式可以使得代碼耦合度降低,各個處理器像鏈表一樣鏈接起來,互相除了鏈接關係外耦合度很低。
下面我將我程序demo貼出來做示例(SpringBoot項目):
① TxProcessor(基類)
package com.pinganfu.processor;
import org.web3j.protocol.core.methods.response.Transaction;
public abstract class TxProcessor {
public abstract Object process(Transaction transaction);
}
② TransferTxProcessor(轉賬交易處理器)
@Component(value="transferTxProcessor")
@Order(value=1)
public class TransferTxProcessor extends TxProcessor{
@Autowired(required=false)
@Qualifier("mintTxProcessor")
private TxProcessor txProcessor;
@Override
public Object process(Transaction transaction) {
System.out.println("TransferTxProcessor transaction process...");
if(txProcessor != null){
return txProcessor.process(transaction);
}
return null;
}
}
③ MintTxProcessor(鑄幣交易處理器)
@Component(value="mintTxProcessor")
@Order(2)
public class MintTxProcessor extends TxProcessor{
@Autowired(required=false)
@Qualifier(value="claimOwnerShipTxProcessor")
private TxProcessor txProcessor;
@Override
public Object process(Transaction transaction) {
System.out.println("MintTxProcessor transaction process...");
if(txProcessor != null){
return txProcessor.process(transaction);
}
return null;
}
}
④ 測試類MainTest
@Controller
public class MainTest {
@Autowired
@Qualifier(value="transferTxProcessor")
private TxProcessor processor;
@RequestMapping("/test")
public String test(){
Transaction transaction = new Transaction();
processor.process(transaction);
return "fuhang";
}
}
運行程序後控制檯輸出結果如下:
TransferTxProcessor transaction process...
MintTxProcessor transaction process...
隨後我們想在責任鏈上繼續添加處理器只需要創建新的處理器類就ok,這個降低了程序之間的耦合度。
你們的意見或者建議是我成長道路上的推動力