责任链模式
- gitee代码实现地址
1. 背景
- 需求: 实现过滤
- 需求2: 直接写好,不用修改的那种的过滤,就是可以从配置文件中读取的过滤器,然后加入到过滤器队列中。
- 需求3:可以在决定在哪里停止过滤,不用进行下一步的过滤。
- 需求4:在去的时候进行一个过滤,在回来的时候进行另一个过滤。
2.实现
- 链式编程实现filter
package chainOfResponsibility; import com.sun.org.apache.bcel.internal.generic.GETFIELD; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.concurrent.Semaphore; /* * * 实现方式0:在主类中进行过滤。 * * 实现方式1,进行链式编程 * 实现方式2: 可以把链条加进来 * 实现方式3:sevlet中的过滤,递归的过程 * */ public class FilterChainI {
public static void main(String[] args) {
Message msg = new Message("你好 <script>, 大家都喜欢ssm"); FilterChain fc = new FilterChain(); fc.add(new HtmlFilter()).add(new SensitiveFilter()); fc.doFilter(msg); System.out.println(msg.getMsg()); } } class Message {
String msg; Message(String s) {
this.msg = s; } public void setMsg(String msg) {
this.msg = msg; } public String getMsg() {
return msg; } } interface Filter {
public void doFilter(Message s); } class HtmlFilter implements Filter{
@Override public void doFilter(Message s) {
String t = s.getMsg().replaceAll("<", "["); t = t.replaceAll(">", "]"); s.setMsg(t); } } class SensitiveFilter implements Filter {
@Override public void doFilter(Message s) {
String t = s.getMsg().replaceAll("ssm", "happy"); s.setMsg(t); } } class FilterChain {
List<Filter> filters; FilterChain() {
filters = new ArrayList<>(); } public FilterChain add(Filter filter) {
filters.add(filter); return this; } public void doFilter(Message s) {
for (Filter f: filters) {
f.doFilter(s); } } }
讯享网
- 可以把链连接起来
讯享网package chainOfResponsibility; import javafx.collections.transformation.FilteredList; import java.io.File; import java.util.ArrayList; import java.util.List; /* * * * 实现方式2:链式添加 * */ public class FilterChainII {
public static void main(String[] args) {
Message msg = new Message("你好 <script>, 大家都喜欢ssm"); FilterChain2 fc = new FilterChain2(); fc.add(new HtmlFilter()); fc.add(new SensitiveFilter()); fc.doFilter(msg); System.out.println(msg.getMsg()); } } class FilterChain2 {
List<Filter> filters = new ArrayList<>(); public void add(Filter f) {
filters.add(f); } public void doFilter(Message s) {
for (Filter f : filters) {
f.doFilter(s); } } }
3. 实际应用
1. 过滤器
- 实现1: 使用数组实现顺序表
- 使用递归调用
- fc可以说是next指针,指向下一个需要执行的filter。
- 此处的fc是使用index进行实现的
- 优点分析
- 控制的流程放在了filterChain里面。
- 这样就算用户没有设置next,filterChain也可以保证安全。
- 细节
- index–;实现可以重复使用过滤器
- 把filterChain改成 filter next更容易理解
package chainOfResponsibility; import java.util.ArrayList; import java.util.List; /* * * 经典servlet的实现版本 * */ public class FilterChainIV {
public static void main(String[] args) {
MyFilterChain fc = new MyFilterChain(); fc.add(new MyHtmlFilter()).add(new MySensitiveFilter()); MyResponse res = new MyResponse(); MyRequest req = new MyRequest(); fc.doFilter(req, res, fc); System.out.println("req = " + req.msg); System.out.println("resp = " + res.msg); fc.doFilter(req, res, fc); System.out.println("req = " + req.msg); // 进行二次过滤,或者进行别的过滤。 System.out.println("resp = " + res.msg); } } class MyRequest {
String msg = ""; } class MyResponse {
String msg = ""; } interface MyFilter {
public void doFilter(MyRequest req, MyResponse resp, MyFilter next); } class MyFilterChain implements MyFilter{
List<MyFilter>filters = new ArrayList<>(); int index = 0; public MyFilterChain add(MyFilter filter) {
filters.add(filter); return this; } @Override public void doFilter(MyRequest req, MyResponse resp, MyFilter next) {
if (index >= filters.size()) return ; MyFilter filter = filters.get(index); index++; filter.doFilter(req, resp, next); index--; // 进行回溯,否则没法进行重新过滤了 } } class MyHtmlFilter implements MyFilter{
@Override public void doFilter(MyRequest req, MyResponse resp, MyFilter next) {
req.msg += "Req.htmlFilter-->"; next.doFilter(req, resp, next); // 如果从这里不进行递归调用,就不进行下一步处理了 resp.msg += "Resp.htmlFilter-->"; } } class MySensitiveFilter implements MyFilter{
@Override public void doFilter(MyRequest req, MyResponse resp, MyFilter next) {
req.msg += "Req.sensitiveFilter-->"; next.doFilter(req, resp, next); // 有用户自己决定是否进行下一步的调用 resp.msg += "Resp.sensitiveFilter-->"; } }
- 实现2:使用链表实现顺序表
讯享网package chainOfResponsibility.v5; import java.io.FileNotFoundException; import java.lang.reflect.Field; /* * * 使用链表直接实现FilterChain * * 属性, Filter next * 除了RuntimeException与其子类,以及错误(Error),其他的都是检查异常(绝对的大家族)。 * * * */ public class FilterChianI {
public static void main(String[] args) {
Filter htmlFilter = new HtmlFitler();
htmlFilter.setNext(new SesitiveFilter()); Requeset req = new Requeset(); Response res = new Response();
htmlFilter.doFilter(req, res); System.out.println(req.msg); System.out.println(res.msg); } } abstract class Filter {
private Filter next; public Filter setNext(Filter next){
this.next = next; return this; } public abstract void doFilter(Requeset req, Response resp); public Filter getNext() throws NullPointerException{
if (this.next != null) return this.next; else throw new NullPointerException("没有设置next!!!请设置在调用"); } } class Requeset {
String msg = ""; } class Response {
String msg = ""; } class HtmlFitler extends Filter {
@Override public void doFilter(Requeset req, Response resp) {
req.msg += "Req.htmlFilter->"; Filter nx = super.getNext(); nx.doFilter(req, resp); resp.msg += "Resp.htmlFilter->"; } } class SesitiveFilter extends Filter {
@Override public void doFilter(Requeset req, Response resp) {
req.msg += "Req.sensitiveFilter->"; //getNext().doFilter(req, resp); // 报错 resp.msg += "Resp.sensitiveFilter->"; } }
- 此处设置如果没有设置next就抛出一个空指针异常,提醒用户只有在设置了之后才可以进行next的调用。
- 把Filter设置成一个链表,next就是Filter类型
- Fitler是一个抽象类。
- 当然可以实现链式的添加也可以实现链条的连接。
- 类图
2. 日志记录
需求: 我们创建抽象类 AbstractLogger,带有详细的日志记录级别。然后我们创建三种类型的记录器,都扩展了 AbstractLogger。每个记录器消息的级别是否属于自己的级别,如果是则相应地打印出来,否则将不打印并把消息传给下一个记录器。
- 菜鸟教程示例和第二种实现过滤器完全相同的思路,就不重复代码了。
- 类图(来自菜鸟教程)

4. 责任链模式分析
1. 定义
顾名思义,责任链模式(Chain of Responsibility Pattern)为请求创建了一个接收者对象的链。这种模式给予请求的类型,对请求的发送者和接收者进行解耦。这种类型的设计模式属于行为型模式。
在这种模式中,通常每个接收者都包含对另一个接收者的引用。如果一个对象不能处理该请求,那么它会把相同的请求传给下一个接收者,依此类推。
2. 类图
3. 优缺点分析
- 优点
- 允许动态的增加和删除职责,且由用户决定是否执行某种操作。
- 实现了**作对象和操作的解耦。
- 缺点
- 系统复杂度提高,容易出错
- 影响性能,出现递归调用,容易造成栈溢出
4. 适用场景
- 由用户确定实现怎样的处理的流程。
- 不确定是否需要添加这种处理的情况。
- 把任务分解,大的任务分解成小步进行处理。
最后
- gitee代码实现地址


版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/66571.html