真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

「設(shè)計模式」責(zé)任鏈模式-創(chuàng)新互聯(lián)

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

創(chuàng)新互聯(lián)建站是專業(yè)的永清網(wǎng)站建設(shè)公司,永清接單;提供網(wǎng)站建設(shè)、成都網(wǎng)站設(shè)計,網(wǎng)頁設(shè)計,網(wǎng)站設(shè)計,建網(wǎng)站,PHP網(wǎng)站建設(shè)等專業(yè)做網(wǎng)站服務(wù);采用PHP框架,可快速的進行永清網(wǎng)站開發(fā)網(wǎng)頁制作和功能擴展;專業(yè)做搜索引擎喜愛的網(wǎng)站,專業(yè)的做網(wǎng)站團隊,希望更多企業(yè)前來合作!文章目錄
    • 「設(shè)計模式」責(zé)任鏈模式
    • 一、概述
    • 二、結(jié)構(gòu)
    • 三、案例實現(xiàn)
    • 四、優(yōu)缺點
    • 五、應(yīng)用場景
    • 六、模擬過濾器機制
    • 七、拓展
    • 八、小結(jié)

一、概述

責(zé)任鏈模式(Chain of Responsibility Pattern)為請求創(chuàng)建了一個接收者對象的鏈。這種模式給予請求的類型,對請求的發(fā)送者和接收者進行解耦。這種類型的設(shè)計模式屬于行為型模式。

在這種模式中,通常每個接收者都包含對另一個接收者的引用。如果一個對象不能處理該請求,那么它會把相同的請求傳給下一個接收者,依此類推。

在現(xiàn)實生活中,常常會出現(xiàn)這樣的事例:一個請求有多個對象可以處理,但每個對象的處理條件或權(quán)限不同。例如,公司員工請假,可批假的領(lǐng)導(dǎo)有部門負責(zé)人、副總經(jīng)理、總經(jīng)理等,但每個領(lǐng)導(dǎo)能批準(zhǔn)的天數(shù)不同,員工必須根據(jù)自己要請假的天數(shù)去找不同的領(lǐng)導(dǎo)簽名,也就是說員工必須記住每個領(lǐng)導(dǎo)的姓名、電話和地址等信息,這增加了難度。這樣的例子還有很多,如找領(lǐng)導(dǎo)出差報銷、生活中的“擊鼓傳花”游戲等。

在計算機軟硬件中也有相關(guān)例子,如總線網(wǎng)中數(shù)據(jù)報傳送,每臺計算機根據(jù)目標(biāo)地址是否同自己的地址相同來決定是否接收;還有異常處理中,處理程序根據(jù)異常的類型決定自己是否處理該異常;還有 Struts2 的攔截器、JSP 和 Servlet 的 Filter 等,所有這些,如果用責(zé)任鏈模式都能很好解決。


二、結(jié)構(gòu)

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

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

三、案例實現(xiàn)

現(xiàn)需要開發(fā)一個請假流程控制系統(tǒng)。請假一天以下的假只需要小組長同意即可;請假1天到3天的假還需要部門經(jīng)理同意;請求3天到7天還需要總經(jīng)理同意才行。

image-20221224230104795

請假條

public class LeaveRequest {private String name;//姓名
    private int num;//請假天數(shù)
    private String content;//請假內(nèi)容

    public LeaveRequest(String name, int num, String content) {this.name = name;
        this.num = num;
        this.content = content;
    }

    public String getName() {return name;
    }

    public int getNum() {return num;
    }

    public String getContent() {return content;
    }
}

處理者抽象類

public abstract class Handler {protected final static int NUM_ONE = 1;
    protected final static int NUM_THREE = 3;
    protected final static int NUM_SEVEN = 7;

    //該領(lǐng)導(dǎo)處理的請假天數(shù)區(qū)間
    private int numStart;
    private int numEnd;

    //領(lǐng)導(dǎo)上面還有領(lǐng)導(dǎo)
    private Handler nextHandler;

    //設(shè)置請假天數(shù)范圍 上不封頂
    public Handler(int numStart) {this.numStart = numStart;
    }

    //設(shè)置請假天數(shù)范圍
    public Handler(int numStart, int numEnd) {this.numStart = numStart;
        this.numEnd = numEnd;
    }

    //設(shè)置上級領(lǐng)導(dǎo)
    public void setNextHandler(Handler nextHandler){this.nextHandler = nextHandler;
    }

    //提交請假條
    public final void submit(LeaveRequest leave){if(0 == this.numStart){return;
        }

        //如果請假天數(shù)達到該領(lǐng)導(dǎo)者的處理要求
        if(leave.getNum() >= this.numStart){this.handleLeave(leave);

            //如果還有上級 并且請假天數(shù)超過了當(dāng)前領(lǐng)導(dǎo)的處理范圍
            if(null != this.nextHandler && leave.getNum() >numEnd){this.nextHandler.submit(leave);//繼續(xù)提交
            } else {System.out.println("流程結(jié)束");
            }
        }
    }

    //各級領(lǐng)導(dǎo)處理請假條方法
    protected abstract void handleLeave(LeaveRequest leave);
}

處理者實現(xiàn)類

//小組長
public class GroupLeader extends Handler {public GroupLeader() {//小組長處理1-3天的請假
        super(Handler.NUM_ONE, Handler.NUM_THREE);
    }

    @Override
    protected void handleLeave(LeaveRequest leave) {System.out.println(leave.getName() + "請假" + leave.getNum() + "天," + leave.getContent() + "。");
        System.out.println("小組長審批:同意。");
    }
}

//部門經(jīng)理
public class Manager extends Handler {public Manager() {//部門經(jīng)理處理3-7天的請假
        super(Handler.NUM_THREE, Handler.NUM_SEVEN);
    }

    @Override
    protected void handleLeave(LeaveRequest leave) {System.out.println(leave.getName() + "請假" + leave.getNum() + "天," + leave.getContent() + "。");
        System.out.println("部門經(jīng)理審批:同意。");
    }
}

//總經(jīng)理
public class GeneralManager extends Handler {public GeneralManager() {//部門經(jīng)理處理7天以上的請假
        super(Handler.NUM_SEVEN);
    }

    @Override
    protected void handleLeave(LeaveRequest leave) {System.out.println(leave.getName() + "請假" + leave.getNum() + "天," + leave.getContent() + "。");
        System.out.println("總經(jīng)理審批:同意。");
    }
}

客戶端

public class Client {public static void main(String[] args) {//請假條來一張
        LeaveRequest leave = new LeaveRequest("小黃",8,"身體不適");

        //各位領(lǐng)導(dǎo)
        GroupLeader groupLeader = new GroupLeader();
        Manager manager = new Manager();
        GeneralManager generalManager = new GeneralManager();

        groupLeader.setNextHandler(manager);//小組長的領(lǐng)導(dǎo)是部門經(jīng)理
        manager.setNextHandler(generalManager);//部門經(jīng)理的領(lǐng)導(dǎo)是總經(jīng)理
        //之所以在這里設(shè)置上級領(lǐng)導(dǎo),是因為可以根據(jù)實際需求來更改設(shè)置,如果實戰(zhàn)中上級領(lǐng)導(dǎo)人都是固定的,則可以移到領(lǐng)導(dǎo)實現(xiàn)類中。

        //提交申請
        groupLeader.submit(leave);
    }
}

image-20221225013843388


四、優(yōu)缺點

優(yōu)點

  • 降低耦合度,使請求的發(fā)送者和接收者解耦,便于靈活的、可插拔的定義請求處理過程;

  • 簡化、封裝了請求的處理過程,并且這個過程對客戶端而言是透明的,以便于動態(tài)地重新組織鏈以及分配責(zé)任,增強請求處理的靈活性;

  • 可以從職責(zé)鏈任何一個節(jié)點開始,也可以隨時改變內(nèi)部的請求處理規(guī)則,每個請求處理者都可以去動態(tài)地指定他的繼任者;

  • 職責(zé)鏈可簡化對象間的相互連接。它們僅需保持一個指向其后繼者的引用,而不需保持它所有的候選接受者的引用;

  • 增加新的請求處理類很方便。

缺點

  • 不能保證請求一定被接收。既然一個請求沒有明確的接收者,那么就不能保證它一定會被處理;
  • 該請求可能一直到鏈的末端都得不到處理。一個請求也可能因該鏈沒有被正確配置而得不到處理;
  • 系統(tǒng)性能將受到一定影響,而且在進行代碼調(diào)試時不太方便;可能會造成循環(huán)調(diào)用。

五、應(yīng)用場景
  • 有多個對象可以處理一個請求,哪個對象處理該請求由運行時刻自動確定。
  • 可動態(tài)指定一組對象處理請求,或添加新的處理者。
  • 在不明確指定請求處理者的情況下,向多個處理者中的一個提交請求。

六、模擬過濾器機制

在JavaWeb應(yīng)用開發(fā)中,F(xiàn)ilterChain是職責(zé)鏈(過濾器)模式的典型應(yīng)用,以下是Filter的模擬實現(xiàn)分析:

  • 模擬web請求Request以及web響應(yīng)Response

    public interface Request{}
    
    public interface Response{}
  • 模擬web過濾器Filter

    public interface Filter {public void doFilter(Request req,Response res,FilterChain c);
     }
  • 模擬實現(xiàn)具體過濾器

    public class FirstFilter implements Filter {@Override
        public void doFilter(Request request, Response response, FilterChain chain) {System.out.println("過濾器1 前置處理");
    
            // 先執(zhí)行所有request再倒序執(zhí)行所有response
            chain.doFilter(request, response);
    
            System.out.println("過濾器1 后置處理");
        }
    }
    
    public class SecondFilter  implements Filter {@Override
        public void doFilter(Request request, Response response, FilterChain chain) {System.out.println("過濾器2 前置處理");
    
            // 先執(zhí)行所有request再倒序執(zhí)行所有response
            chain.doFilter(request, response);
    
            System.out.println("過濾器2 后置處理");
        }
    }
  • 模擬實現(xiàn)過濾器鏈FilterChain

    public class FilterChain {private Listfilters = new ArrayList();
    
        private int index = 0;
    
        // 鏈?zhǔn)秸{(diào)用
        public FilterChain addFilter(Filter filter) {this.filters.add(filter);
            return this;
        }
    
        public void doFilter(Request request, Response response) {if (index == filters.size()) {return;
            }
            Filter filter = filters.get(index);
            index++;
            filter.doFilter(request, response, this);
        }
    }
  • 測試類

    public class Client {public static void main(String[] args) {Request  req = null;
            Response res = null ;
    
            FilterChain filterChain = new FilterChain();
            filterChain.addFilter(new FirstFilter()).addFilter(new SecondFilter());
            filterChain.doFilter(req,res);
        }
    }

    運行效果和我們javaweb中的效果一樣,要想理解為什么打印順序會這樣,需要重點去理解FilterChain類中doFilter方法:
    責(zé)任鏈模式模擬過濾器鏈案例


七、拓展

職責(zé)鏈模式存在以下兩種情況。

  • **純的職責(zé)鏈模式:**一個請求必須被某一個處理者對象所接收,且一個具體處理者對某個請求的處理只能采用以下兩種行為之一:自己處理(承擔(dān)責(zé)任);把責(zé)任推給下家處理。
  • 不純的職責(zé)鏈模式:允許出現(xiàn)某一個具體處理者對象在承擔(dān)了請求的一部分責(zé)任后又將剩余的責(zé)任傳給下家的情況,且一個請求可以最終不被任何接收端對象所接收。

純的責(zé)任鏈模式的實際例子很難找到,一般看到的例子均是不純的責(zé)任鏈模式的實現(xiàn)。


八、小結(jié)
  • 在職責(zé)鏈模式里,很多對象由每一個對象對其下家的引用而連接起來形成一條鏈。請求在這個鏈上傳遞,直到鏈上的某一個對象決定處理此請求。發(fā)出這個請求的客戶端并不知道鏈上的哪一個對象最終處理這個請求,這使得系統(tǒng)可以在不影響客戶端的情況下動態(tài)地重新組織鏈和分配責(zé)任。
  • 職責(zé)鏈模式的主要優(yōu)點在于可以降低系統(tǒng)的耦合度,簡化對象的相互連接,同時增強給對象指派職責(zé)的靈活性,增加新的請求處理類也很方便;其主要缺點在于不能保證請求一定被接收,且對于比較長的職責(zé)鏈,請求的處理可能涉及到多個處理對象,系統(tǒng)性能將受到一定影響,而且在進行代碼調(diào)試時不太方便。

參考

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

黑馬程序員

你是否還在尋找穩(wěn)定的海外服務(wù)器提供商?創(chuàng)新互聯(lián)www.cdcxhl.cn海外機房具備T級流量清洗系統(tǒng)配攻擊溯源,準(zhǔn)確流量調(diào)度確保服務(wù)器高可用性,企業(yè)級服務(wù)器適合批量采購,新人活動首月15元起,快前往官網(wǎng)查看詳情吧


網(wǎng)頁標(biāo)題:「設(shè)計模式」責(zé)任鏈模式-創(chuàng)新互聯(lián)
分享URL:http://weahome.cn/article/dooepj.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部