责任链模式
1.责任链模式概念
个人的理解:为了避免处理请求信息逻辑耦合在一起,将负责不同职责的业务逻辑拆分开,并串成一条"链",由每个模块负责处理各自的业务逻辑,最终得到我们预期的结果。
2.责任链模式优点
(1)、降低了对象之间的耦合度。该模式使得一个对象无须知道到底是哪一个对象处理其请求以及链的结构,发送者和接收者也无须拥有对方的明确信息。
(2)、增强了系统的可扩展性。可以根据需要增加新的请求处理类,满足开闭原则。
(3)、增强了给对象指派职责的灵活性。当工作流程发生变化,可以动态地改变链内的成员或者调动它们的顺序,也可动态地新增或者删除责任。
(4)、责任链简化了对象之间的连接。每个对象只需保持一个指向其后继者的引用,不需保持其他所有处理者的引用,这避免了使用众多的 if 或者 if···else 语句。
(5)、责任分担。每个类只需要处理自己该处理的工作,不该处理的传递给下一个对象完成,明确各类的责任范围,符合类的单一职责原则。
3.责任链模式缺点
(1)、不能保证每个请求一定被处理。由于一个请求没有明确的接收者,所以不能保证它一定会被处理,该请求可能一直传到链的末端都得不到处理。
(2)、对比较长的职责链,请求的处理可能涉及多个处理对象,系统性能将受到一定影响。
(3)、职责链建立的合理性要靠客户端来保证,增加了客户端的复杂性,可能会由于职责链的错误设置而导致系统出错,如可能会造成循环调用。
4.责任链模式中角色
(1)、请求类角色:创建处理链,并向链头的具体处理对象提交请求
(2)、抽象处理者角色:定义一个处理请求的接口,包含抽象处理方法和一个后继连接
(3)、具体处理者角色:实现抽象处理者的处理方法,判断能否处理本次请求,如果可以处理请求则处理,否则将该请求转给它的后继者
5.代码实现
业务场景:对请求体内容进行过滤,先对请求内容的url进行过滤,再对请求内容的表情进行过滤。
(1)、定义过滤接口
/**
* @author ppeng
* @date 2020/9/23 18:36
* @description
*/
public interface Filter {
/**
* 过滤
* @param msg
* @return
*/
boolean doFilter(Msg msg);
}
(2)、url过滤类
/**
* @author ppeng
* @date 2020/9/23 18:38
* @description
*/
public class UrlFilter implements Filter{
@Override
public boolean doFilter(Msg msg) {
if(null == msg){
return false;
}
msg.setMsg(msg.getMsg().replaceAll("www.baidu.com", "http://www.baidu.com"));
System.out.println(msg.getMsg());
return true;
}
}
(3)、表情过滤类
/**
* @author ppeng
* @date 2020/9/23 18:38
* @description
*/
public class FaceFilter implements Filter{
@Override
public boolean doFilter(Msg msg) {
if(null == msg){
return false;
}
msg.setMsg(msg.getMsg().replace(":)","^_^ ^_^ ^_^"));
System.out.println(msg.getMsg());
return true;
}
}
(4)、责任链类
/**
* @author ppeng
* @date 2020/9/23 18:39
* @description
*/
public class FilterChain implements Filter {
private static List<Filter> filters = new ArrayList<>();
public FilterChain add(Filter filer){
filters.add(filer);
return this;
}
@Override
public boolean doFilter(Msg msg) {
if(CollectionUtils.isEmpty(filters)){
return false;
}
for (Filter filter : filters) {
if(!filter.doFilter(msg)){
return false;
}
}
return true;
}
}
(4)、实体类
/**
* @author ppeng
* @date 2020/9/23 19:04
* @description
*/
@Data
public class Msg {
private String msg;
}
(5)、测试类
/**
* @author ppeng
* @date 2020/9/23 18:44
* @description
*/
public class Test {
public static void main(String[] args) {
Msg msg = new Msg();
msg.setMsg("hello,www.baidu.com!!! :)");
FilterChain filterChain = new FilterChain();
filterChain.add(new UrlFilter()).add(new FaceFilter());
filterChain.doFilter(msg);
}
}
(6)、输出结果
请求内容:hello,www.baidu.com!!! :)
Url过滤后内容:hello,http://www.baidu.com!!! :)
Face过滤后内容:hello,http://www.baidu.com!!! ^_^ ^_^ ^_^