责任链模式(Chain of Responsibility Pattern
)为请求创建了一个接收者的链,请求在这条链上传递,直到链上的某个接收者处理此请求,或者每个对象都可以处理请求,并传给“下家”,直到最终链上每个对象都处理完。
responsibility [rɪˌspɑːnsəˈbɪləti] 责任,负责 pattern [ˈpætərn] 模式,方式;
这种模式可以避免请求发送者与接收者耦合在一起,让多个对象都有可能接收请求。
在Java
中,异常机制就是一种责任链模式。一个try
语句可以对应多个catch
,如果第一个catch
不匹配,就自动跳到第二个catch
。
(链表方式定义职责链)请假条审批流程,我们可以在请假处理流程中,增加新的“副总经理”角色,审批大于等于10天,小于20天的请假。审批流程变为:
① 如果请假天数小于3天,主任审批;
② 如果请假天数大于等于3天,小于10天,经理审批;
③ 大于等于10天,小于20天的请假,副总经理审批;
④ 如果大于等于20天,小于30天,总经理审批;
⑤ 如果大于等于30天,提示拒绝;
该过程的实现大致有以下几个步骤:
步骤一:封装请假的基本信息public class Vacation {
private String employee;
private int duration;
private String reason;
public Vacation(String employee, int duration, String reason) {
this.employee = employee;
this.duration = duration;
this.reason = reason;
}
public String getEmployee() {
return employee;
}
public void setEmployee(String employee) {
this.employee = employee;
}
public int getDuration() {
return duration;
}
public void setDuration(int duration) {
this.duration = duration;
}
public String getReason() {
return reason;
}
public void setReason(String reason) {
this.reason = reason;
}
}
步骤二:定义抽象处理者(Leader
)
public abstract class Leader {
protected String name;
protected Leader nextLeader;
public Leader(String name) {
this.name = name;
}
public void setNextLeader(Leader nextLeader) {
this.nextLeader = nextLeader;
}
public abstract void handleVacation(Vacation vacation);
}
第三步:定义具体处理者
主任:
public class Director extends Leader {
public Director(String name) {
super(name);
}
@Override
public void handleVacation(Vacation vacation) {
if (vacation.getDuration() < 3) {
System.out.println("员工:" + vacation.getEmployee() + ",请假天数:" + vacation.getDuration());
System.out.println("主任:" + this.name + ",审批通过!");
} else {
if (this.nextLeader != null) {
this.nextLeader.handleVacation(vacation);
}
}
}
}
经理:
public class Manager extends Leader {
public Manager(String name) {
super(name);
}
@Override
public void handleVacation(Vacation vacation) {
if (vacation.getDuration() < 10) {
System.out.println("员工:" + vacation.getEmployee() + ",请假天数:" + vacation.getDuration());
System.out.println("经理:" + this.name + ",审批通过!");
} else {
if (this.nextLeader != null) {
this.nextLeader.handleVacation(vacation);
}
}
}
}
副总经理:
public class ViceGeneralManager extends Leader {
public ViceGeneralManager(String name) {
super(name);
}
@Override
public void handleVacation(Vacation vacation) {
if (vacation.getDuration() < 20) {
System.out.println("员工:" + vacation.getEmployee() + ",请假天数:" + vacation.getDuration());
System.out.println("副总经理:" + this.name + ",审批通过!");
} else {
if (this.nextLeader != null) {
this.nextLeader.handleVacation(vacation);
}
}
}
}
总经理:
public class GeneralManager extends Leader {
public GeneralManager(String name) {
super(name);
}
@Override
public void handleVacation(Vacation vacation) {
if (vacation.getDuration() < 30) {
System.out.println("员工:" + vacation.getEmployee() + ",请假天数:" + vacation.getDuration());
System.out.println("总经理:" + this.name + ",审批通过!");
} else {
if (this.nextLeader != null) {
this.nextLeader.handleVacation(vacation);
}
}
}
}
第四步:测试
class Client {
public static void main(String[] args) {
Leader director = new Director("段誉");
Leader manager = new Manager("鸠摩智");
Leader viceGeneralManager = new ViceGeneralManager("萧峰");
Leader generalManager = new GeneralManager("扫递僧");
director.setNextLeader(manager);
manager.setNextLeader(viceGeneralManager);
viceGeneralManager.setNextLeader(generalManager);
Vacation vacation = new Vacation("慕容复", 28, "回姑苏");
director.handleVacation(vacation);
System.out.println("审批流程:" + director.name + "-->" + manager.name + "-->" + viceGeneralManager.name + "-->" + generalManager.name);
}
}
// 员工:慕容复,请假天数:28
// 总经理:扫递僧,审批通过!
// 审批流程:段誉-->鸠摩智-->萧峰-->扫递僧
3 案例2
创建抽象类AbstractLogger
,带有详细的日志记录级别。然后创建三种类型的记录器,都扩展了AbstractLogger
。每个记录器消息的级别是否属于自己的级别,如果是则相应地打印出来,否则将不打印并把消息传给下一个记录器。
public abstract class AbstractLogger {
public static int INFO = 1;
public static int DEBUG = 2;
public static int ERROR = 3;
protected int level;
protected AbstractLogger nextLogger;
public void setNextLogger(AbstractLogger nextLogger) {
this.nextLogger = nextLogger;
}
public void logMessage(int level, String message) {
if (this.level < level) {
write(message);
}
if (nextLogger != null) {
nextLogger.logMessage(level, message);
}
}
abstract protected void write(String message);
}
步骤二:创建扩展了该记录器类的实体类
ConsoleLogger
:
public class ConsoleLogger extends AbstractLogger {
public ConsoleLogger(int level) {
this.level = level;
}
@Override
protected void write(String message) {
System.out.println("Standard Console::Logger: " + message);
}
}
ErrorLogger
:
public class ErrorLogger extends AbstractLogger {
public ErrorLogger(int level) {
this.level = level;
}
@Override
protected void write(String message) {
System.out.println("Error Console::Logger:" + message);
}
}
FileLogger
:
public class FileLogger extends AbstractLogger {
public FileLogger(int level) {
this.level = level;
}
@Override
protected void write(String message) {
System.out.println("File Console::Logger: " + message);
}
}
第三步:测试
创建不同类型的记录器,赋予它们不同的错误级别,并在每个记录器中设置下一个记录器。每个记录器中的下一个记录器代表的是链的一部分:
public class ChainPatternDemo {
private static AbstractLogger getChainOfLoggers() {
AbstractLogger consoleLogger = new ConsoleLogger(AbstractLogger.INFO);
AbstractLogger errorLogger = new ErrorLogger(AbstractLogger.ERROR);
AbstractLogger fileLogger = new FileLogger(AbstractLogger.DEBUG);
consoleLogger.setNextLogger(errorLogger);
errorLogger.setNextLogger(fileLogger);
return consoleLogger;
}
public static void main(String[] args) {
AbstractLogger loggerChain = getChainOfLoggers();
loggerChain.logMessage(AbstractLogger.INFO, "This is an information");
loggerChain.logMessage(AbstractLogger.DEBUG, "This is a debug level information");
loggerChain.logMessage(AbstractLogger.ERROR, "This is an error information");
}
}
// Standard Console::Logger: This is a debug level information
// Standard Console::Logger: This is an error information
//File Console::Logger: This is an error information
参考
https://zhuanlan.zhihu.com/p/368932005
https://www.runoob.com/design-pattern/chain-of-responsibility-pattern.html
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)