8.5責(zé)任鏈模式??????
8.5.1概念
? 責(zé)任鏈模式定義了一系列的處理器對(duì)象,每個(gè)處理器對(duì)象都包含對(duì)鏈表中下一個(gè)處理器對(duì)象的引用。在這條請(qǐng)求鏈條中,每當(dāng)一個(gè)請(qǐng)求發(fā)生時(shí),它就會(huì)被傳遞給鏈表的下一個(gè)處理器對(duì)象,直到某個(gè)處理器對(duì)象處理該請(qǐng)求為止。
8.5.2場(chǎng)景
? 在我們公司內(nèi)部審批流程中,若某個(gè)員工提交了請(qǐng)假申請(qǐng),需要經(jīng)過上級(jí)的一系列的審批過程,例如小組長(zhǎng)審批、部門經(jīng)理審批、人事部審批、總經(jīng)理審批等。這些審批過程可以采用責(zé)任鏈模式來(lái)實(shí)現(xiàn),將每個(gè)審批者看作一個(gè)處理器,若某個(gè)處理者無(wú)法處理該申請(qǐng),則將該申請(qǐng)傳遞給下一個(gè)處理者,直到有一個(gè)處理者同意或拒絕該申請(qǐng)為止。
8.5.3優(yōu)勢(shì) / 劣勢(shì)
- 降低耦合度:請(qǐng)求發(fā)送者和接收者之間不直接交互,而是通過責(zé)任鏈上的多個(gè)對(duì)象進(jìn)行交互,從而降低了它們之間的耦合度
- 增強(qiáng)靈活性:可以動(dòng)態(tài)地增加或刪除處理器,從而改變請(qǐng)求的處理順序和方式
- 提高可擴(kuò)展性:因?yàn)槊總€(gè)處理器都只負(fù)責(zé)處理自己能夠處理的請(qǐng)求,所以可以方便地添加新的處理器來(lái)處理新的請(qǐng)求類型
- 請(qǐng)求未處理:若沒有任何一個(gè)處理器能夠處理該請(qǐng)求,則該請(qǐng)求將被忽略
- 系統(tǒng)性能降低:由于責(zé)任鏈中可能包含大量的處理器,因此可能會(huì)影響系統(tǒng)的性能
8.5.4責(zé)任鏈模式可分為
- 處理者Handler:定義一個(gè)處理請(qǐng)求的接口,包含一個(gè)處理請(qǐng)求的抽象方法和指向下一個(gè)處理者的鏈接
- 具體處理者ConcreteHandler:實(shí)現(xiàn)處理請(qǐng)求的方法,并判斷能否處理請(qǐng)求,若能夠處理請(qǐng)求則進(jìn)行處理,否則將請(qǐng)求傳遞給下一個(gè)處理者
- 客戶端:創(chuàng)建并組裝處理者對(duì)象鏈,并將請(qǐng)求發(fā)送到鏈上的第一個(gè)處理者
8.5.5責(zé)任鏈模式
package com.technologystatck.designpattern.mode.chainofresponsibility;
public class ChainOfResponsibility {
public static void main(String[] args) {
//創(chuàng)建處理者實(shí)例
ConcreteHandler handlerA = new ConcreteHandler();
ConcreteHandler handlerB = new ConcreteHandler();
//...可以繼續(xù)創(chuàng)建其他處理者實(shí)例
//構(gòu)建責(zé)任鏈
handlerA.setNextHandler(handlerB);
//...可以繼續(xù)構(gòu)建責(zé)任鏈
//發(fā)送請(qǐng)求
Request request = new Request(/*請(qǐng)求參數(shù)*/);
handlerA.handleRequest(request);
}
}
//1.處理者:定義處理請(qǐng)求的接口
interface Handler{
//處理請(qǐng)求的方法
void handleRequest(Request request);
//設(shè)置下一個(gè)處理者的方法
void setNextHandler(Handler nextHandler);
}
//2.具體處理者:實(shí)現(xiàn)處理請(qǐng)求
class ConcreteHandler implements Handler{
private Handler nextHandler;
//具體處理者自己的判斷條件
private boolean canHandle(Request request){
//根據(jù)具體情況判斷是否能夠處理請(qǐng)求
/**
* 放入自己的判斷條件
*/
return true;
}
@Override
public void handleRequest(Request request) {
//根據(jù)具體情況處理請(qǐng)求,若無(wú)法處理則轉(zhuǎn)發(fā)給下一個(gè)處理者
if(canHandle(request)){
//處理請(qǐng)求的邏輯
}else if(nextHandler !=null){
nextHandler.handleRequest(request);
}else{
//無(wú)法處理請(qǐng)求的邏輯,如打印日志等等
}
}
@Override
public void setNextHandler(Handler nextHandler) {
this.nextHandler=nextHandler;
}
}
8.5.6實(shí)戰(zhàn)
8.5.6.1題目描述
小明所在的公司請(qǐng)假需要在OA系統(tǒng)上發(fā)布申請(qǐng),整個(gè)請(qǐng)求流程包括多個(gè)處理者,每個(gè)處理者負(fù)責(zé)處理不同范圍的請(qǐng)假天數(shù),如果一個(gè)處理者不能處理請(qǐng)求,就會(huì)將請(qǐng)求傳遞給下一個(gè)處理者,請(qǐng)你實(shí)現(xiàn)責(zé)任鏈模式,可以根據(jù)請(qǐng)求天數(shù)找到對(duì)應(yīng)的處理者。
審批責(zé)任鏈由主管(Supervisor), 經(jīng)理(Manager)和董事(Director)組成,他們分別能夠處理3天、7天和10天的請(qǐng)假天數(shù)。如果超過10天,則進(jìn)行否決。
8.5.6.2輸入描述
第一行是一個(gè)整數(shù)N(1 <= N <= 100), 表示請(qǐng)求申請(qǐng)的數(shù)量。
接下來(lái)的N行,每行包括一個(gè)請(qǐng)求申請(qǐng)的信息,格式為"姓名 請(qǐng)假天數(shù)"文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-818469.html
8.5.6.3輸出描述
對(duì)于每個(gè)請(qǐng)假請(qǐng)求,輸出一行,表示該請(qǐng)求是否被批準(zhǔn)。如果被批準(zhǔn)/否決,輸出被哪一個(gè)職級(jí)的人批準(zhǔn)/否決。文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-818469.html
8.5.6.4代碼
package com.technologystatck.designpattern.mode.chainofresponsibility;
import java.util.Scanner;
public class Test {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int nums=scanner.nextInt();
scanner.nextLine();
//組織責(zé)任鏈
LeaveHandler director = new Director();
LeaveHandler manager = new Manager(director);
LeaveHandler supervisor = new Supervisor(manager);
for(int i=0;i<nums;i++){
String[] input = scanner.nextLine().split(" ");
if(input.length==2){
String name=input[0];
int days=Integer.parseInt(input[1]);
LeaveRequest request = new LeaveRequest(name, days);
supervisor.handleRequest(request);
}else{
System.out.println("Invalid input");
return;
}
}
}
}
//請(qǐng)求類
class LeaveRequest{
private String name;
private int days;
public LeaveRequest(String name, int days) {
this.name = name;
this.days = days;
}
public String getName() {
return name;
}
public int getDays() {
return days;
}
}
//處理者:定義接口
interface LeaveHandler{
void handleRequest(LeaveRequest request);
}
//具體處理者:可以有多個(gè),負(fù)責(zé)具體處理,主要分為Supervisor、Manager、Director
//主管類
class Supervisor implements LeaveHandler{
//最多3天請(qǐng)假審批
private static final int MAX_DAYS_SUPERVISOR_CAN_APPROVE=3;
//設(shè)置下一個(gè)處理器對(duì)象
private LeaveHandler nextHandler;
public Supervisor(LeaveHandler nextHandler) {
this.nextHandler = nextHandler;
}
@Override
public void handleRequest(LeaveRequest request) {
//若請(qǐng)假的天數(shù)小于當(dāng)前處理者所能審批的最大天數(shù),則直接審批通過,否則繼續(xù)傳遞給下一個(gè)處理者。
if(request.getDays()<=MAX_DAYS_SUPERVISOR_CAN_APPROVE){
System.out.println(request.getName()+" Approved by Supervisor.");
}else if(nextHandler !=null){
//若下一個(gè)處理器不為空,就直接傳給下一個(gè)處理器
nextHandler.handleRequest(request);
}else{
System.out.println(request.getName()+"Denied by Supervisor.");
}
}
}
//經(jīng)理類
class Manager implements LeaveHandler{
//最多7天請(qǐng)假審批
private static final int MAX_DAYS_SUPERVISOR_CAN_APPROVE=7;
//設(shè)置下一個(gè)處理器對(duì)象
private LeaveHandler nextHandler;
public Manager(LeaveHandler nextHandler) {
this.nextHandler = nextHandler;
}
@Override
public void handleRequest(LeaveRequest request) {
if(request.getDays()<=MAX_DAYS_SUPERVISOR_CAN_APPROVE){
System.out.println(request.getName()+" Approved by Manager.");
}else if(nextHandler !=null){
nextHandler.handleRequest(request);
}else{
System.out.println(request.getName()+" Denied by Manager.");
}
}
}
//總監(jiān)類
class Director implements LeaveHandler{
private static final int MAX_DAYS_SUPERVISOR_CAN_APPROVE=10;
@Override
public void handleRequest(LeaveRequest request) {
if(request.getDays()<=MAX_DAYS_SUPERVISOR_CAN_APPROVE){
System.out.println(request.getName()+" Approved by Director.");
}else{
System.out.println(request.getName()+" Denied by Director.");
}
}
}
8.5.7總結(jié)
- 優(yōu)點(diǎn):每個(gè)處理者只負(fù)責(zé)處理與自己相關(guān)的請(qǐng)求,客戶端不需要具體時(shí)哪個(gè)處理者處理請(qǐng)求
- 總結(jié):類似過濾器中的鏈?zhǔn)教幚?,一個(gè)請(qǐng)求不斷地在鏈?zhǔn)街袀魅胂乱粋€(gè)處理者,直到有一個(gè)處理者能處理該請(qǐng)求
- 場(chǎng)景:適用于一個(gè)請(qǐng)求會(huì)被多個(gè)處理者進(jìn)行處理,并且整條責(zé)任鏈模式中會(huì)有合適的處理者來(lái)處理請(qǐng)求
到了這里,關(guān)于笨蛋學(xué)設(shè)計(jì)模式行為型模式-責(zé)任鏈模式【18】的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!