责任链模式介绍
责任链模式是一种行为类型的模式,以某种顺序组合一组同类型的对象用来处理一个业务请求,如果组内某个对象处理了请求,处理完毕返回并作出相应的相应(response),否则,会把请求按次序转发给组内另一个对象处理。
举个现实生活中的例子来更好的理解此模式,假如你有一个难题要解决,如果你能自己解决掉,不会再请别人帮忙,否则,你会请朋友帮忙,如果你朋友也解决不了,他会继续请他的朋友帮忙解决,依次类推直到问题解决,或者最终问题没有解决。
类似上面的例子,假如你接到一个需求,帮助一个保健公司做一个分析类的应用,此应用需要通过一个界面来收集客户的资料,资料类型有很多种,如文本文件,doc 文件,excel, 语音,图片,视频等。。。,你需要把这些格式的数据存到数据库中,用户不关心也不需要知道他们上传的数据如何存储的。
你需要开发不同的处理器来保存不同格式的数据,例如,文本文件处理器不能处理 mp3文件,这时,你可以利用责任链模式来解决,你可以创建不同的对象来处理不同格式的数据并把这些对象链接起来,当一个请求过来被一个对象接收时,它会判断能否处理此请求包含特定格式的数据,如果能,自己处理并返回,否则,转发下一个对象进行处理。此模式解耦了请求的发送者和接收者,发送者不需要知道具体执行的对象,使增加新处理器更容易,修改原有处理器不影响其他处理器,符合开闭原则
责任链模式详解
GoF 对责任链模式的定义:
“Avoid coupling the sender of a request to its receiver by giving more than one object a chance to handle the request. Chain the receiving objects and pass the request along the chain until an object handles it.”
翻译如下:
通过一组对象处理请求来解耦请求的发送者和接收者,把接收者链接起来,一个接一个的过滤请求并判断能否处理。
此模式主要参与者
Handler
- 定义一个接口来处理请求
ConcreteHandler
- 处理特定的请求
- 能否访问它的后继者
- 如果能自己处理就自己处理,否则,把请求转发到下一个ConcreteHandler
Client
- 初始化一个请求传给对象链中的一个对象
责任链模式代码实现
public interface Handler {
void setHandler(Handler handler);
void process(File file);
String getHandlerName();
}
public class File {
private final String fileName;
private final String fileType;
private final String filePath;
public File(String fileName, String fileType, String filePath) {
this.fileName = fileName;
this.fileType = fileType;
this.filePath = filePath;
}
public String getFileName() {
return fileName;
}
public String getFileType() {
return fileType;
}
public String getFilePath() {
return filePath;
}
}
public class TextFileHandler implements Handler {
private Handler handler;
private String handlerName;
public TextFileHandler(String handlerName) {
this.handlerName = handlerName;
}
@Override
public void setHandler(Handler handler) {
this.handler = handler;
}
@Override
public void process(File file) {
if (file.getFileType().equals("text")) {
System.out.println("Process and save text file ... by" + handlerName);
} else if (handler != null) {
System.out.println(handlerName + " forwards request to" + handler.getHandlerName());
handler.process(file);
} else {
System.out.println("File not supported");
}
}
@Override
public String getHandlerName() {
return this.handlerName;
}
}
public class DocFileHandler implements Handler {
private Handler handler;
private String handlerName;
public DocFileHandler(String handlerName) {
this.handlerName = handlerName;
}
@Override
public void setHandler(Handler handler) {
this.handler = handler;
}
@Override
public void process(File file) {
if (file.getFileType().equals("doc")) {
System.out.println("Process and save doc file ... by" + handlerName);
} else if (handler != null) {
System.out.println(handlerName + " forwards request to" + handler.getHandlerName());
} else {
System.out.println("File not supported");
}
}
@Override
public String getHandlerName() {
return this.handlerName;
}
}
public class TestChainOfResponsibility {
public static void main(String[] args) {
Handler textHandler = new TextFileHandler("Text Handler");
Handler docHandler = new DocFileHandler("Doc Handler");
textHandler.setHandler(docHandler);
File file = new File("abc.txt","text","d:");
textHandler.process(file);
file = new File("abc.doc", "doc", "e:");
textHandler.process(file);
file = new File("abc.sh", "sh", "f:");
textHandler.process(file);
}
}
输出结果:
Process and save text file … byText Handler
Text Handler forwards request toDoc Handler
Process and save doc file … byDoc Handler
Text Handler forwards request toDoc Handler
File not supported
例子源码:链接
jdk 责任链模式的应用
- java.util.logging.Logger#log()
- javax.servlet.Filter#doFilter()