JAVA设计模式之责任链模式

来源:互联网 发布:mac软件要怎么下载 编辑:程序博客网 时间:2024/06/06 13:24

1. 什么是责任链模式?

创建多个对象,使这些对象行成一条链,并沿着这条链传递请求,直到链上的某个对象决定处理此请求,这就是责任链模式。


接收请求的对象形成一条链,这些对象在链上具有层级关系的。这些对象可以处理请求,也可以传递请求,直到有对象处理此请求为止。


责任链模式归根结底就是多重判断,和if、else if是相同的功能,但是条件比较多的情况下,使用if/else会造成代码臃肿,不易于扩展和维护。责任链模式将判断语句放到处理对象中,这样将请求和处理解耦,便于扩展和维护。


责任链模式是对象的行为模式

2. 角色

 

图片源于网络

抽象处理者角色(Handler):此类一般是一个抽象类,其中定义了处理请求的抽象方法(handleMessage,示例中为write方法)和传递请求给下一个处理对象的方法(handleRequest)。其中有一个自身的引用(nextHandler),用于接收下一个请求者对象。


具体处理者角色(ConcreteHandler):具体请求者必须继承完善Handler类,提供自己的处理方法实现。可以有多个具体处理者,一般这些具体处理者之间具有层级关系。


调用者角色(Client):调用者有一个Handler的引用,一般此类是一个工具类,专门用于生成对象链。将请求发送者和请求处理者解耦。

    

3. 优点

(1)将请求的发送者和接收者解耦,请求发送者不知道请求是怎么传递的,也不知道请求是哪个对象处理的。

(2)良好的扩展性。可以很方便的扩展请求处理对象。

(3)可以解决多层if/else嵌套造成的代码臃肿问题,将判断放到处理类中简洁明了。

4. 缺点

(1)不能保证请求一定被处理,如果没有对象处理请求可能掉落到链的末端。

(2)很可能出现请求处理对象循环调用,出现死循环的情况。

(3)责任链模式会增加系统理解难度,不容易观察运行时的特征,增加调试难度,有碍于排查bug。

5. 使用场景

(1)当有多个对象处理一个请求的情况下可以使用责任链模式。

(2)代码中存在多层if/else嵌套的情况下,可以使用责任链模式将判断放到到处理类中。

6. 示例代码

(1)抽象处理者角色

/** * 日志抽象处理者 */public abstract class AbstractLogHandler {//当前日志级别protected int level;//下一个请求处理者protected AbstractLogHandler nextHandler;public void setNextHandler(AbstractLogHandler nextHandler) {this.nextHandler = nextHandler;}public AbstractLogHandler getNextHandler() {return nextHandler;}/** * 传递请求 */public final void handleRequest(int logLevel,String msg){if(this.level<logLevel){//当前处理对象没有处理权限getNextHandler().handleRequest(logLevel, msg);}else{write(msg);}}/** * 处理请求:输出日志记录抽象方法,需子类提供实现 */public abstract void write(String msg);}

(2)具体处理者角色

/** * 普通日志信息具体处理类 */public class InfoLogHandle extends AbstractLogHandler {public InfoLogHandle(int level) {this.level=level;}@Overridepublic void write(String msg) {System.out.println("info:"+msg);}}
/** * 警告日志具体处理类 */public class WarnLogHandle extends AbstractLogHandler {public WarnLogHandle(int level) {this.level=level;}@Overridepublic void write(String msg) {System.out.println("warn:"+msg);}}
/** * 错误日志信息具体处理类 */public class ErrorLogHandle extends AbstractLogHandler {public ErrorLogHandle(int level) {this.level=level;}@Overridepublic void write(String msg) {System.out.println("error:"+msg);}}

(3)调用者角色

/** * 日志对象生成工具类 */public class LoggerManager {// 普通日志级别public static int INFO = 1;// 警告日志级别public static int WARN = 2;// 错误日志级别public static int ERROR = 3;/** * 生成处理链 * 一般处理对象之间存在一个层级关系 * 此处,INFO权限最低,ERROR权限最高 */public static AbstractLogHandler getLogger() {AbstractLogHandler info = new InfoLogHandle(INFO);AbstractLogHandler warn = new WarnLogHandle(WARN);AbstractLogHandler error = new ErrorLogHandle(ERROR);// 设置处理链info.setNextHandler(warn);warn.setNextHandler(error);return info;}}

(4)测试代码

public class Client {public static void main(String[] args) {AbstractLogHandler logger=LoggerManager.getLogger();logger.handleRequest(LoggerManager.INFO, "用户A登录系统");//error级别的日志,将跳过info和warn,进入error处理者logger.handleRequest(LoggerManager.ERROR, "系统错误");//warn级别将跳过info级别的处理者logger.handleRequest(LoggerManager.WARN,"系统警告");}}

 

(5)测试结果

info:用户A登录系统error:系统错误warn:系统警告

参考文章http://www.jianshu.com/p/d65eeeed6754

【四川乐山程序员联盟,欢迎大家加群相互交流学习5 7 1 8 1 4 7 4 3】

 

 

 

原创粉丝点击