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

詳解Java設計模式之職責鏈模式

 更新時間:2023年05月26日 09:23:22   作者:十二Y  
責任鏈模式是一種行為設計模式,使多個對象都有機會處理請求,從而避免請求的發(fā)送者和接收者之間的耦合關(guān)系,文中通過代碼示例給大家介紹的非常詳細,需要的朋友可以參考下

職責鏈模式

1、職責鏈模式介紹

責任鏈模式(Chain of Responsibility Pattern)是一種行為設計模式,使多個對象都有機會處理請求,從而避免請求的發(fā)送者和接收者之間的耦合關(guān)系。將這個對象連成一條鏈,并沿著這條鏈傳遞該請求,直到有一個對象處理它為止。

在責任鏈模式中,請求通過一條鏈傳遞,每個對象都有機會處理請求。當一個對象無法處理請求時,它會將請求傳遞給鏈中的下一個對象,直到找到能夠處理請求的對象為止。這種方式可以動態(tài)地組織和管理對象,使得請求發(fā)送者和接收者之間解耦,提高系統(tǒng)的靈活性和可擴展性。

1.1 職責鏈模式基本實現(xiàn)

職責鏈模式結(jié)構(gòu)圖:

責任鏈模式包含以下幾個角色:

  • 抽象處理者(Handler):定義了一個處理請求的接口,通常包含一個指向下一個處理者的引用,用于構(gòu)建責任鏈。
  • 具體處理者(ConcreteHandler):實現(xiàn)抽象處理者接口,具體處理請求的邏輯。如果可以處理請求,則處理請求;否則,將請求傳遞給下一個處理者。

Handler類,定義一個處理請示的接口:

/**
 * @author Shier
 * CreateTime 2023/5/20 16:04
 * 處理請求的接口
 */
public abstract class Handler {
    protected Handler successor;
    /**
     * 設置繼承者
     * @param successor
     */
    public void setSuccessor(Handler successor) {
        this.successor = successor;
    }
    public abstract void handleRequest(int request);
}

ConcreteHandler類,具體處理者類,處理它所負責的請求,可訪問它的 后繼者,如果可處理該請求,就處理之,否則就將該請求轉(zhuǎn)發(fā)給它的后繼 者。

ConcreteHandler1,當請求數(shù)為0~10則有權(quán)處理,否則轉(zhuǎn)到下一位:

/**
 * @author Shier
 * CreateTime 2023/5/20 16:06
 */
public class ConcreteHandler1 extends Handler {
    @Override
    public void handleRequest(int request) {
        if (request >= 0 && request < 10) {
            // 當前處理者權(quán)限 0 ~ 9
            System.out.println(this.getClass().getSimpleName() + "處理了請求" + request);
        } else if (successor != null) {
            // 轉(zhuǎn)移給下一個處理者
            successor.handleRequest(request);
        }
    }
}

ConcreteHandler2,當請求數(shù)為10~20則有權(quán)處理,否則轉(zhuǎn)到下一位。

/**
 * @author Shier
 * CreateTime 2023/5/20 16:06
 */
public class ConcreteHandler2 extends Handler {
    @Override
    public void handleRequest(int request) {
        if (request >= 10 && request < 20) {
            // 當前處理者權(quán)限 10 ~ 19
            System.out.println(this.getClass().getSimpleName() + "處理了請求" + request);
        } else if (successor != null) {
            // 轉(zhuǎn)移給下一個處理者
            successor.handleRequest(request);
        }
    }
}

ConcreteHandler3,當請求數(shù)為20~99則有權(quán)處理,否則轉(zhuǎn)到下一位

/**
 * @author Shier
 * CreateTime 2023/5/20 16:06
 */
public class ConcreteHandler3 extends Handler {
    @Override
    public void handleRequest(int request) {
        if (request >= 20 && request < 100) {
            // 當前處理者權(quán)限 20 ~ 99
            System.out.println(this.getClass().getSimpleName() + "處理了請求" + request);
        } else if (successor != null) {
            // 轉(zhuǎn)移給下一個處理者
            successor.handleRequest(request);
        }
    }
}

客戶端代碼,向鏈上的具體處理者對象提交請求。

/**
 * @author Shier
 * CreateTime 2023/5/20 16:09
 */
public class ChainClient {
    public static void main(String[] args) {
        ConcreteHandler1 handler1 = new ConcreteHandler1();
        ConcreteHandler2 handler2 = new ConcreteHandler2();
        ConcreteHandler3 handler3 = new ConcreteHandler3();
        // 設置職責鏈上下關(guān)系
        handler1.setSuccessor(handler2);
        handler2.setSuccessor(handler3);
        // 請求
        int[] request = {15, 67, 8, 9, 46, 1, 5, 23, 41};
        // 循環(huán)給最小矗立著提交請求,不同的數(shù)額,得不同的權(quán)限處理者處理
        for (int i : request) {
            handler1.handleRequest(i);
        }
    }
}

2、具體例子說明

在公司請假或者升職加薪,需要通過經(jīng)理、總監(jiān)、總經(jīng)理的批準,不同身份有不同的權(quán)限。當然可以直接直接找總經(jīng)理給你升職加薪??

2.1 不使用職責鏈模式 - 加薪 / 請假

升值加薪:經(jīng)理是沒有權(quán)限的,要上報給總監(jiān),總監(jiān)的回復也是沒有權(quán)限管,只能再上報到總經(jīng)理才有處理的權(quán)限

請假:經(jīng)理只能處理請假兩天的申請,再多就不可以。必須要上報給上司才有權(quán)限去處理這個請求。

// 申請類
public class Request {
    // 申請類別
    private String requestType;
    public String getRequestType(){
        return this.requestType;
    }
    public void setRequestType(String value){
        this.requestType = value;
    }
    //申請內(nèi)容
    private String requestContent;
    public String getRequestContent(){
        return this.requestContent;
    }
    public void setRequestContent(String value){
        this.requestContent = value;
    }
    // 數(shù)量
    private int number;
    public int getNumber(){
        return this.number;
    }
    public void setNumber(int value){
        this.number = value;
    }
}
//管理者
public class Manager{
    protected String name;
    public Manager(String name){
        this.name = name;
    }
    public void getResult(String managerLevel,Request request){
        if (managerLevel == "經(jīng)理"){
          if (request.getRequestType()=="請假" && request.getNumber()<=2)
            System.out.println(this.name+":"+request.getRequestContent()+" 數(shù)量:"+request.getNumber()+"天,被批準");
          else 
            System.out.println(this.name+":"+request.getRequestContent()+" 數(shù)量:"+request.getNumber()+"天,我無權(quán)處理");
        }
        else if (managerLevel == "總監(jiān)"){
          if (request.getRequestType()=="請假" && request.getNumber()<=5)
            System.out.println(this.name+":"+request.getRequestContent()+" 數(shù)量:"+request.getNumber()+"天,被批準");
          else 
            System.out.println(this.name+":"+request.getRequestContent()+" 數(shù)量:"+request.getNumber()+"天,我無權(quán)處理");
        }
        else if (managerLevel == "總經(jīng)理"){
          if (request.getRequestType()=="請假")
            System.out.println(this.name+":"+request.getRequestContent()+" 數(shù)量:"+request.getNumber()+"天,被批準");
          else if (request.getRequestType()=="加薪" && request.getNumber()<=5000)
            System.out.println(this.name+":"+request.getRequestContent()+" 數(shù)量:"+request.getNumber()+"元,被批準");
          else if (request.getRequestType()=="加薪" && request.getNumber()>5000)
            System.out.println(this.name+":"+request.getRequestContent()+" 數(shù)量:"+request.getNumber()+"元,再說吧");
        }
    }
}

客戶端:

public class Test {
    public static void main(String[] args) {
        Manager manager = new Manager("金利");
        Manager director = new Manager("宗劍");
        Manager generalManager = new Manager("鐘精勵");
        Request request = new Request();
        request.setRequestType("加薪");
        request.setRequestContent("Shier請求加薪");
        request.setNumber(10000); 
        // 不同身份的人有不同的權(quán)限,進行處理結(jié)果
        manager.getResult("經(jīng)理", request);
        director.getResult("總監(jiān)", request);
        generalManager.getResult("總經(jīng)理", request);
        Request request2 = new Request();
        request2.setRequestType("請假");
        request2.setRequestContent("Shier請假");
        request2.setNumber(3); // 權(quán)限級別
        manager.getResult("經(jīng)理", request2);
        director.getResult("總監(jiān)", request2);
        generalManager.getResult("總經(jīng)理", request2);
    }
}

通過上面的程序,會發(fā)現(xiàn)一個問題管理者類,里面的方法比較長,太多的分支判斷。類的責任太多,就違背了單一職責原則,同時增加新的項目時,要去修改這個方法,就違背了開發(fā) - 封閉原則。下面就要用到職責鏈模式要簡化這樣開發(fā)業(yè)務場景 。

2.2 職責鏈模式 - 加薪 / 請假

將上面的程序進行重構(gòu),得到的代碼結(jié)構(gòu)圖如下:

Request請求類:

/**
 * @author Shier
 * 申請類
 */
public class Request {
    // 申請類別
    private String requestType;
    public String getRequestType() {
        return this.requestType;
    }
    public void setRequestType(String value) {
        this.requestType = value;
    }
    //申請內(nèi)容
    private String requestContent;
    public String getRequestContent() {
        return this.requestContent;
    }
    public void setRequestContent(String value) {
        this.requestContent = value;
    }
    // 數(shù)量
    private int number;
    public int getNumber() {
        return this.number;
    }
    public void setNumber(int value) {
        this.number = value;
    }
}

抽象管理者:

/**
 * @author Shier
 * CreateTime 2023/5/20 16:33
 * 抽象管理這類
 */
public abstract class Manager {
    protected String name;
    public Manager(String name) {
        this.name = name;
    }
    /**
     * 設置管理者上級
     */
    protected Manager superior;
    public void setSuperior(Manager superior) {
        this.superior = superior;
    }
    /**
     * 請求申請
     *
     * @param request
     */
    public abstract void requestApplications(Request request);
}

經(jīng)理類就可以去繼承這個'管理者'類,只需重寫 '申請請求' 的方法

/**
 * @author Shier
 * CreateTime 2023/5/20 16:34
 * 普通經(jīng)理類
 */
public class CommonManager extends Manager {
    public CommonManager(String name) {
        super(name);
    }
    @Override
    public void requestApplications(Request request) {
        if (request.getRequestType() == "請假" && request.getNumber() <= 2) {
            System.out.println(this.name + ":" + request.getRequestContent() + " 數(shù)量:" + request.getNumber() + "天,被批準");
        } else if (this.superior != null) {
            this.superior.requestApplications(request);
        }
    }
}

總監(jiān)同樣繼承抽象管理類

/**
 * @author Shier
 * CreateTime 2023/5/20 16:36
 * 總監(jiān)
 */
public class Director extends Manager {
    public Director(String name) {
        super(name);
    }
    @Override
    public void requestApplications(Request request) {
        if (request.getRequestType() == "請假" && request.getNumber() <= 5) {
            System.out.println(this.name + ":" + request.getRequestContent() + " 數(shù)量:" + request.getNumber() + "天,被批準");
        } else if (this.superior != null) {
            this.superior.requestApplications(request);
        }
    }
}

總經(jīng)理同樣繼承管理者類,總經(jīng)理的權(quán)限就是全部都需要處理。

/**
 * @author Shier
 * CreateTime 2023/5/20 16:36
 * 總經(jīng)理
 */
public class GeneralManager extends Manager {
    public GeneralManager(String name) {
        super(name);
    }
    @Override
    public void requestApplications(Request request) {
        if (request.getRequestType() == "請假") {
            System.out.println(this.name + ":" + request.getRequestContent() + " 數(shù)量:" + request.getNumber() + "天,被批準");
        } else if (request.getRequestType() == "加薪" && request.getNumber() <= 5000) {
            System.out.println(this.name + ":" + request.getRequestContent() + " 數(shù)量:" + request.getNumber() + "元,被批準");
        } else if (request.getRequestType() == "加薪" && request.getNumber() > 5000) {
            System.out.println(this.name + ":" + request.getRequestContent() + " 數(shù)量:" + request.getNumber() + "元,再說吧");
        }
    }
}

測試類:

/**
 * @author Shier
 */
public class ChainClient {
    public static void main(String[] args) {
        CommonManager manager = new CommonManager("大明經(jīng)理");
        Director director = new Director("大大明總監(jiān)");
        GeneralManager generalManager = new GeneralManager("大大大明總經(jīng)理");
        // 設置管理者之間上下級關(guān)系 經(jīng)理 => 總監(jiān) => 總經(jīng)理
        manager.setSuperior(director);
        director.setSuperior(generalManager);
        // 加薪 5000
        Request request = new Request();
        request.setRequestType("加薪");
        request.setRequestContent("Shier請求加薪");
        request.setNumber(5000);
        // 從自己最近的上司開始請求也就是經(jīng)理
        manager.requestApplications(request);
        // 加薪10000
        Request request1 = new Request();
        request1.setRequestType("加薪");
        request1.setRequestContent("Shier請求加薪");
        request1.setNumber(10000);
        manager.requestApplications(request1);
        // 請假一天
        Request request2 = new Request();
        request2.setRequestType("請假");
        request2.setRequestContent("Shier請假");
        request2.setNumber(1);
        manager.requestApplications(request2);
        // 請假四天
        Request request3 = new Request();
        request3.setRequestType("請假");
        request3.setRequestContent("Shier請假");
        request3.setNumber(4);
        manager.requestApplications(request3);
    }
}

最后得到的結(jié)果:

由于我們把原來的一個 '管理者' 類改成了一個抽象類和三個具體類, 此時類之間的靈活性就大大增加了,如果我們需要擴展新的管理者類別,只需要增加子類就可以。比如這個例子增加一個 '集團總裁' 類,完全是沒有問題的,只需要修改 '總經(jīng)理類' 即可,并不影響其他類代碼。

這樣使用職責鏈模式可以更加清晰這些代碼之間的關(guān)系,不像最上面的一個類里面多個判斷語句,看起來都很難維護。好了,再總結(jié)一下職責鏈模式

3、職責鏈模式總結(jié)

職責鏈模式的好處

  • 當客戶提交一個請求時,請求是沿鏈傳遞直至有一個 ConcreteHandler 對象負責處理它。
  • 降低耦合:接收者和發(fā)送者都沒有對方的明確信息,且鏈中的對 象自己也并不知道鏈的結(jié)構(gòu)。結(jié)果是職責鏈可簡化對象的相互連接,它們僅 需保持一個指向其后繼者的引用,而不需保持它所有的候選接受者的引用。降低了代碼之間耦合度。
  • 靈活性:隨時地增加或修改處理一個請求的結(jié)構(gòu)。增強了給對象指派職責的靈活性。

優(yōu)點:

  • 將請求發(fā)送者和接收者解耦,可以避免請求發(fā)送者與接收者之間的直接耦合,增強了代碼的可維護性。
  • 可以動態(tài)地新增或修改請求處理順序,提高了程序的靈活性和可擴展性。
  • 可以進行請求的攔截、分流等操作,方便進行統(tǒng)計和日志記錄等處理。
  • 可以根據(jù)需要對請求的處理進行單獨的測試,便于代碼測試和調(diào)試。
  • 解耦發(fā)送者和接收者:職責鏈模式可以將發(fā)送者和接收者解耦,發(fā)送者不需要知道請求的具體處理者是誰,而處理者也不需要知道請求的發(fā)送者是誰,從而提高系統(tǒng)的靈活性。
  • 動態(tài)組合和擴展性:職責鏈模式允許動態(tài)地向鏈中添加或刪除處理者,以適應不同的業(yè)務需求,增強了系統(tǒng)的可擴展性。
  • 可配置性:通過調(diào)整鏈中處理者的順序,可以靈活地配置處理流程,滿足不同的處理優(yōu)先級或條件。

缺點:

  • 請求的保證:沒有明確的處理者處理請求的保證。請求可能到達鏈的末尾而沒有被處理,這需要在設計時進行合理的考慮。
  • 性能考慮:由于鏈中的請求需要依次傳遞給每個處理者,因此在處理大量請求時可能會影響性能。
  • 可能導致系統(tǒng)變得復雜:當鏈過長或者處理者過多時,職責鏈模式可能會導致系統(tǒng)變得復雜,難以理解和維護。

使用場景:

  • 處理復雜的請求處理流程,例如購物車結(jié)算、審批流程等復雜業(yè)務中。
  • 需要動態(tài)指定請求的處理順序或者動態(tài)添加新的請求處理者時。
  • 處理日志記錄、緩存等攔截器的場景。例如在Spring中,就應用了責任鏈模式來實現(xiàn)Interceptor攔截器。
  • 多個對象可以處理同一請求,但具體的處理者在運行時可變或不確定的情況下,可以使用職責鏈模式。
  • 需要動態(tài)組合處理流程或動態(tài)調(diào)整處理順序的情況下,職責鏈模式可以提供靈活性和可配置性。
  • 需要在不明確請求的發(fā)送者和接收者之間建立松耦合關(guān)系的情況下,職責鏈模式可以解耦對象之間的關(guān)系。

以上就是詳解Java設計模式之職責鏈模式的詳細內(nèi)容,更多關(guān)于Java 職責鏈模式的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • SpringBoot+Druid開啟監(jiān)控頁面的實現(xiàn)示例

    SpringBoot+Druid開啟監(jiān)控頁面的實現(xiàn)示例

    本文主要介紹了SpringBoot+Druid開啟監(jiān)控頁面的實現(xiàn)示例,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2024-06-06
  • IDEA生成javadoc的實現(xiàn)步驟

    IDEA生成javadoc的實現(xiàn)步驟

    Javadoc是一種用于生成API文檔的工具,它可以根據(jù)代碼中特定格式的注釋自動生成文檔,本文主要介紹了IDEA生成javadoc的實現(xiàn)步驟,感興趣的可以了解一下
    2023-10-10
  • 淺談springboot之JoinPoint的getSignature方法

    淺談springboot之JoinPoint的getSignature方法

    這篇文章主要介紹了springboot之JoinPoint的getSignature方法,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-06-06
  • JVM加載一個類的過程

    JVM加載一個類的過程

    本文主要介紹了JVM加載一個類的過程。具有很好的參考價值,下面跟著小編一起來看下吧
    2017-02-02
  • 客戶端Socket與服務端ServerSocket串聯(lián)實現(xiàn)網(wǎng)絡通信

    客戶端Socket與服務端ServerSocket串聯(lián)實現(xiàn)網(wǎng)絡通信

    這篇文章主要為大家介紹了客戶端Socket與服務端ServerSocket串聯(lián)實現(xiàn)網(wǎng)絡通信的內(nèi)容詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助
    2022-03-03
  • Java利用TCP實現(xiàn)服務端向客戶端消息群發(fā)的示例代碼

    Java利用TCP實現(xiàn)服務端向客戶端消息群發(fā)的示例代碼

    這篇文章主要為大家詳細介紹了Java如何利用TCP協(xié)議實現(xiàn)服務端向客戶端消息群發(fā)功能,文中的示例代碼講解詳細,需要的可以參考下,希望對你有所幫助
    2022-08-08
  • 一篇文章帶你了解Maven的坐標概念以及依賴管理

    一篇文章帶你了解Maven的坐標概念以及依賴管理

    這篇文章主要為大家介紹了Maven的坐標概念以及依賴管理,具有一定的參考價值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2022-01-01
  • Java中常用數(shù)據(jù)類型的輸入輸出詳解

    Java中常用數(shù)據(jù)類型的輸入輸出詳解

    本文主要介紹了Java中幾個常用的數(shù)據(jù)類型是如何輸入和輸出的,例如:Char型、int型、double型、數(shù)組、字符串等,對我們學習java有一定的幫助,感興趣的小伙伴可以跟隨小編一起學習學習
    2021-12-12
  • Java使用Catcher捕獲異常的實現(xiàn)

    Java使用Catcher捕獲異常的實現(xiàn)

    本文主要介紹了Java使用Catcher捕獲異常的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2023-05-05
  • java實現(xiàn)簡易版簡易版dubbo

    java實現(xiàn)簡易版簡易版dubbo

    dubbo是阿里開源的rpc框架,目前是apache頂級開源項目,可以用來構(gòu)建微服務。本文主要介紹了如何通過java實現(xiàn)簡易版的dubbo,感興趣的小伙伴可以了解一下
    2021-11-11

最新評論