设计模式是面向问题、场景而总结产生的设计思路。是解决问题的套路。23 种经典的设计模式。它们又可以分为三大类:创建型、结构型、行为型。
行为型 包含了 观察者模式、模板模式、策略模式、职责链模式、状态模式、迭代器模式、 访问者模式、备忘录模式、命令模式、解释器模式、中介模式 总共11种模式。
责任链模式
责任链模式(Chain of Responsibility Design Pattern) ,通常每个接收者都包含对另一个接收者的引用。如果一个对象不能处理该请求,那么它会把相同的请求传给下一个接收者,依此类推。
1. 主要优点
- 解耦 ,一个对象无须知道到底是哪一个对象处理其请求以及链的结构,发送者和接收者也无须拥有对方的明确信息。
- 可扩展性, 可以根据需要增加新的请求处理类,满足开闭原则。
- 灵活性,当工作流程发生变化,可以动态地改变链内的成员或者调动它们的次序,也可动态地新增或者删除责任。
- 简化,责任链简化了对象之间的连接。每个对象只需保持一个指向其后继者的引用,不需保持其他所有处理者的引用,这避免了使用众多的 if 或者 if···else 语句。
- 责任分担。每个类只需要处理自己该处理的工作,不该处理的传递给下一个对象完成,明确各类的责任范围,符合类的单一职责原则。
2. 代码实现一
以敏感词过滤为例,定义Filter
public interface Filter {
boolean doFilter(String content);
}
public class NegativeWordFilter implements Filter{
@Override
public boolean doFilter(String content) {
boolean checked = true;
if(content.contains("烂")) return false;
return checked;
}
}
public class SensitiveWordFilter implements Filter{
@Override
public boolean doFilter(String content) {
boolean checked = true;
if(content.contains("<script")) return false;
return checked;
}
}
定义FilterChain
public class FilterChain {
private List<Filter> filters = new ArrayList<>();
public void add(Filter filter) {
filters.add(filter);
}
public boolean filter(String sentence){
for(Filter filter:filters) {
if(!filter.doFilter(sentence)) return false;
}
return true;
}
}
运行结果
public class Main {
public static void main(String[] args) {
FilterChain chain = new FilterChain();
chain.add(new NegativeWordFilter());
chain.add(new SensitiveWordFilter());
System.out.println(chain.filter("ni是中国人"));
System.out.println(chain.filter("ni<script>是中国人"));
System.out.println(chain.filter("ni是中国人烂"));
}
}
true
false
false
3. 代码实现二
不需要显示创建FilterChain,通过链表方式存储,代码简单但是理解难一些。
Filter 是抽象类,使用模板方法,定义了handle的处理流程,由子类实现check方法。
public abstract class Filter {
private Filter next;
public void setNext(Filter next) {
this.next = next;
}
public final void handle(String content){
boolean injected = check(content);
if(next!=null&&!injected) {
next.handle(content);
}
}
abstract boolean check(String content);
}
子类实现其check方法,对于有问题的返回false
public class NegativeWordFilter extends Filter {
@Override
boolean check(String content) {
boolean injected = false;
if(content.contains("烂")) {
System.out.println("拒绝");
return true;
}
return injected;
}
}
public class SensitiveWordFilter extends Filter {
@Override
boolean check(String content) {
boolean injected = false;
if(content.contains("<script")) {
System.out.println("拒绝");
return true;
}
return injected;
}
}
通过调用,如果有问题的将会被拒绝。
public class Main {
public static void main(String[] args) {
FilterChain chain = new FilterChain();
chain.add(new NegativeWordFilter());
chain.add(new SensitiveWordFilter());
System.out.println(chain.filter("ni是中国人"));
System.out.println(chain.filter("ni<script>是中国人"));
System.out.println(chain.filter("ni是中国人烂"));
}
}
运行结果
拒绝
拒绝
总结
在责任链模式中, 将请求的发送与接收解耦,让接收对象都能接收这些请求并进行处理,请求的路径是一条链路,请求沿着路径直到被处理。在WEB项目中的Filter、Spring的Interceptor中大量使用了责任链模式,实现了鉴权、限流、记录日志、验证参数等多重功能。
设计模式系列在github上有一个开源项目,主要是本系列博客的demo代码。https://github.com/forestnlp/designpattern
如果您对软件开发、机器学习、深度学习有兴趣请关注本博客,将持续推出Java、软件架构、深度学习相关专栏。
您的支持是对我最大的鼓励。