目录
- 责任链模式
- 责任链模式结构
- 责任链模式适用场景
- 责任链模式优缺点
- 练手题目
- 题目描述
- 输入描述
- 输出描述
- 题解
责任链模式
责任链模式,亦称职责链模式、命令链,是一种行为设计模式,允许你将请求沿着处理者链进行发送。收到请求后,每个处理者均可对请求进行处理,或将其传递给链上的下个处理者。
责任链模式结构
-
处理者(Handler)声明了所有具体处理者的通用接口。该接口通常仅包含单个方法用于请求处理,但有时其还会包含一个设置链上下个处理者的方法。
-
基础处理者(Base Handler)是一个可选的类,你可以将所有处理者共用的样本代码放置在其中。通常情况下,该类中定义了一个保存对于下个处理者引用的成员变量。 客户端可通过将处理者传递给上个处理者的构造函数或设定方法来创建链。该类还可以实现默认的处理行为:确定下个处理者存在后再将请求传递给它。
-
具体处理者(Concrete Handlers)包含处理请求的实际代码。每个处理者接收到请求后,都必须决定是否进行处理,以及是否沿着链传递请求。处理者通常是独立且不可变的,需要通过构造函数一次性地获得所有必要地数据。
-
客户端(Client)可根据程序逻辑一次性或者动态地生成链。值得注意的是,请求可发送给链上的任意一个处理者,而非必须是第一个处理者。
责任链模式通用代码:
//抽象处理者
public abstract class Handler{//下一个处理者private Handler nextHandler;// 对请求做出处理public final Response handleMessage(Request request){Response response = null ;//判断处理级别if(this.getHandlerLever().equals(request.getHandlerLever())){response = this.echo(request);}else{if(this.nextHandler != null){response = this.nextHandler.handleMessage(request);}else{...}return response;}public void setNext(Handler _handler){this.nextHandler = _handler;}//处理级别protected abstract Level getHandlerLevel();//处理任务protected abstract Response echo(Request request);}//具体处理者
public class ConcreteHandler1 extends Handler {//级别protected abstract Level getHandlerLevel(){...
}//处理任务protected abstract Response echo(Request request){...
}
}public class Level{}public class Request{public Level getRequestLevel(){...}
}public class Response{...
}
责任链模式适用场景
-
当程序需要使用不同方式处理不同种类请求, 而且请求类型和顺序预先未知时, 可以使用责任链模式。
-
当必须按顺序执行多个处理者时, 可以使用该模式。
-
如果所需处理者及其顺序必须在运行时进行改变, 可以使用责任链模式。
**识别方法:**该模式可通过一组对象的行为方法间接调用其他对象的相同方法来识别, 而且所有对象都会遵循相同的接口。
责任链模式优缺点
责任链模式优点:
-
你可以控制请求处理的顺序。
-
单一职责原则。 你可对发起操作和执行操作的类进行解耦。
-
开闭原则。 你可以在不更改现有代码的情况下在程序中新增处理者。
责任链模式缺点:
- 部分请求可能未被处理。
练手题目
题目描述
小明所在的公司请假需要在OA系统上发布申请,整个请求流程包括多个处理者,每个处理者负责处理不同范围的请假天数,如果一个处理者不能处理请求,就会将请求传递给下一个处理者,请你实现责任链模式,可以根据请求天数找到对应的处理者。
审批责任链由主管(Supervisor), 经理(Manager)和董事(Director)组成,他们分别能够处理3天、7天和10天的请假天数。如果超过10天,则进行否决。
输入描述
第一行是一个整数N(1 <= N <= 100), 表示请求申请的数量。
接下来的N行,每行包括一个请求申请的信息,格式为"姓名 请假天数"
输出描述
对于每个请假请求,输出一行,表示该请求是否被批准。如果被批准/否决,输出被哪一个职级的人批准/否决。
题解
初始解法:
import java.util.Scanner;/*** 抽象处理器类,定义了责任链的基本结构*/
abstract class Handler {public final static int SUPERVISOR_LEVEL_REQUEST = 1;public final static int MANAGER_LEVEL_REQUEST = 2;public final static int DIRECTOR_LEVEL_REQUEST = 3;private Handler nextHandler;private int level = 0;public Handler(int level) {this.level = level;}/*** 处理请求的方法* @param request 需要处理的请求* @return 处理结果*/public final Response handleRequest(Request request) {if (this.level == request.getRequestLevel()) {return this.response(request);} else {if (this.nextHandler != null) {return this.nextHandler.handleRequest(request);} else {return new Response("Request denied");}}}/*** 设置下一个处理器* @param nextHandler 下一个处理器*/public void setNext(Handler nextHandler) {this.nextHandler = nextHandler;}/*** 具体的响应方法,由子类实现* @param request 需要处理的请求* @return 处理结果*/protected abstract Response response(Request request);
}/*** 主管处理*/
class SupervisorHandler extends Handler {public SupervisorHandler() {super(Handler.SUPERVISOR_LEVEL_REQUEST);}@Overrideprotected Response response(Request request) {System.out.println(request.getName() + " Approved by Supervisor.");return new Response("Approved by Supervisor");}
}/*** 经理处理*/
class ManagerHandler extends Handler {public ManagerHandler() {super(Handler.MANAGER_LEVEL_REQUEST);}@Overrideprotected Response response(Request request) {System.out.println(request.getName() + " Approved by Manager.");return new Response("Approved by Manager");}
}/*** 董事处理*/
class DirectorHandler extends Handler {public DirectorHandler() {super(Handler.DIRECTOR_LEVEL_REQUEST);}@Overrideprotected Response response(Request request) {System.out.println(request.getName() + " Approved by Director.");return new Response("Approved by Director");}
}/*** 请求类,包含请求的详细信息*/
class Request {private String name;private int level = 0;private int nums;public Request(String name, int nums) {this.name = name;this.nums = nums;if (nums > 0 && nums <= 3) {level = Handler.SUPERVISOR_LEVEL_REQUEST;} else if (nums > 3 && nums <= 5) {level = Handler.MANAGER_LEVEL_REQUEST;} else if (nums > 5 && nums <= 10) {level = Handler.DIRECTOR_LEVEL_REQUEST;} else {level = -1;}}public int getRequestLevel() { return this.level; }public String getName() { return this.name; }public int getNums() { return this.nums; }
}/*** 响应类,包含处理结果*/
class Response {private String message;public Response(String message) {this.message = message;}public String getMessage() {return this.message;}
}public class Main {public static void main(String[] args) {Scanner scanner = new Scanner(System.in);// 创建处理器链SupervisorHandler supervisorHandler = new SupervisorHandler();ManagerHandler managerHandler = new ManagerHandler();DirectorHandler directorHandler = new DirectorHandler();supervisorHandler.setNext(managerHandler);managerHandler.setNext(directorHandler);int n = scanner.nextInt();scanner.nextLine(); while (n-- > 0) {String[] s = scanner.nextLine().split(" ");Request request = new Request(s[0], Integer.parseInt(s[1]));Response response = supervisorHandler.handleRequest(request);if (request.getRequestLevel() == -1) {System.out.println(request.getName() + " Denied by Director.");}}scanner.close();}
}
优化后:
import java.util.Scanner;// 抽象处理器类,定义了责任链的基本结构
abstract class Handler {public final static int SUPERVISOR_LEVEL_REQUEST = 1;public final static int MANAGER_LEVEL_REQUEST = 2;public final static int DIRECTOR_LEVEL_REQUEST = 3;private Handler nextHandler;private int level = 0;// 构造函数,设置处理器的级别public Handler(int _level) {this.level = _level;}// 处理请求的方法public final Response handleMessage(Request request) {if (this.level == request.getRequestLevel()) {return this.response(request);} else {if (this.nextHandler != null) {return this.nextHandler.handleMessage(request);} else {return new Response("Request denied");}}}// 设置下一个处理器public void setNext(Handler _handler) {this.nextHandler = _handler;}protected abstract Response response(Request request);
}// 主管处理
class SupervisorHandler extends Handler {public SupervisorHandler() {super(Handler.SUPERVISOR_LEVEL_REQUEST);}@Overrideprotected Response response(Request request) {System.out.println(request.getName() + " Approved by Supervisor.");return new Response("Approved by Supervisor");}
}// 经理处理
class ManagerHandler extends Handler {public ManagerHandler() {super(Handler.MANAGER_LEVEL_REQUEST);}@Overrideprotected Response response(Request request) {System.out.println(request.getName() + " Approved by Manager.");return new Response("Approved by Manager");}
}// 董事处理
class DirectorHandler extends Handler {public DirectorHandler() {super(Handler.DIRECTOR_LEVEL_REQUEST);}@Overrideprotected Response response(Request request) {System.out.println(request.getName() + " Approved by Director.");return new Response("Approved by Director");}
}// 请求级别的枚举,定义了不同级别的请假天数范围
enum RequestLevel {SUPERVISOR(1, 3),MANAGER(4, 5),DIRECTOR(6, 10);private final int minDays;private final int maxDays;RequestLevel(int minDays, int maxDays) {this.minDays = minDays;this.maxDays = maxDays;}// 根据天数确定请求级别public static RequestLevel fromDays(int days) {for (RequestLevel level : values()) {if (days >= level.minDays && days <= level.maxDays) {return level;}}return null;}public int getValue() {return ordinal() + 1;}
}// 请求类,包含请求的详细信息
class Request {private String name;private int level;private int nums;public Request(String name, int nums) {this.name = name;this.nums = nums;RequestLevel requestLevel = RequestLevel.fromDays(nums);this.level = (requestLevel != null) ? requestLevel.getValue() : -1;}public int getRequestLevel() {return this.level;}public String getName() {return this.name;}public int getNums() {return this.nums;}
}// 响应类,包含处理结果
class Response {private String message;public Response(String message) {this.message = message;}public String getMessage() {return this.message;}
}// 主类
public class Main {public static void main(String[] args) {Scanner scanner = new Scanner(System.in);// 创建处理器链SupervisorHandler supervisorHandler = new SupervisorHandler();ManagerHandler managerHandler = new ManagerHandler();DirectorHandler directorHandler = new DirectorHandler();// 设置处理器链的顺序supervisorHandler.setNext(managerHandler);managerHandler.setNext(directorHandler);int n = scanner.nextInt();scanner.nextLine(); // 处理每个请求while (n-- > 0) {String[] s = scanner.nextLine().split(" ");Request request = new Request(s[0], Integer.parseInt(s[1]));Response response = supervisorHandler.handleMessage(request);if (request.getRequestLevel() == -1) {System.out.println(request.getName() + " Denied by Director.");}}scanner.close();}
}