责任链模式
责任链(Chain of Responsibility)模式为请求创建了一个接收者对象的链。这种模式给予请求的类型,对请求的发送者和接收者进行解耦。这种类型的设计模式属于行为型模式。
使用场景
一个请求对象需要多种任务的处理,通过链式传播对象的场景。
优点
1.职责链对于客户请求是透明的
2.“链”将请求的发送者和处理者解耦
代码演示
日志类级别有debug、info、warn、error的区别,模拟日志类对请求的处理。
日志请求
/**
* 日志类
*/
@AllArgsConstructor
@Data
public class Log {
private Enum logType;
private String content;
}
枚举类型
/**
* 日志类型
*/
public enum LogLevel {
CONSOLE,DEBUG,INFO;
}
日志接口
/**
* 日志接口
*/
public interface ILogger {
void print(String s);
}
console类型日志处理类,通过将请求注册到LinkedBlockingQueue中,当请求注册到console中,take()取出log请求对象处理,并将log对象put到下一个处理类debug类型日志处理类中,如法炮制。
利用take()方法取不出对象就会阻塞的特性,责任链会一直阻塞,直到有新的请求到达,继续处理。
/**
* console日志
*/
@Data
public class ConsoleLogger extends Thread implements ILogger{
private LinkedBlockingQueue<Log> queue = new LinkedBlockingQueue();
private DebugLogger nextLogger;
public ConsoleLogger(DebugLogger nextLogger) {
this.nextLogger = nextLogger;
}
public void process(Log log) throws InterruptedException {
queue.put(log);
}
public void print(String s) {
System.out.println("console日志对象打印:" + s);
}
@Override
public void run() {
while(true){
try {
// take取不出元素会一直在这里阻塞
Log log = queue.take();
// 这里可以加上其他Ilogger的扩展,并根据LogLevel自行判断是否处理
if(log.getLogType() == LogLevel.CONSOLE){ print(log.getContent());}
nextLogger.process(log);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
debug日志处理类
/**
* debug日志
*/
@Data
public class DebugLogger extends Thread implements ILogger {
private LinkedBlockingQueue<Log> queue = new LinkedBlockingQueue();
public void process(Log log) throws InterruptedException {
queue.put(log);
}
@Override
public void print(String s) {
System.out.println("debug日志对象打印:" + s);
}
@Override
public void run() {
while(true){
try {
// take取不出元素会一直在这里阻塞
Log log = queue.take();
// 并根据LogLevel自行判断是否处理
if(log.getLogType() == LogLevel.DEBUG){ print(log.getContent());}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
测试结果
/**
* 异步责任链测试
*/
public class Test {
public static void main(String[] args) throws InterruptedException {
DebugLogger debug = new DebugLogger();
ConsoleLogger console = new ConsoleLogger(debug);
// 创建日志
Log log = new Log(LogLevel.CONSOLE,"Hi, i'm Andy");
Log log2 = new Log(LogLevel.DEBUG,"Hi, i'm Ming");
//启动线程
new Thread(console).start();
new Thread(debug).start();
//责任链调用
console.process(log);
console.process(log2);
//运行结果
// console日志对象打印:Hi, i'm Andy
// debug日志对象打印:Hi, i'm Ming
}
}