设计模式之责任链模式

一、责任链模式

顾名思义,责任链模式(Chain of Responsibility Pattern)为请求创建了一个接收者对象的链。这种模式给予请求的类型,对请求的发送者和接收者进行解耦。这种类型的设计模式属于行为型模式。

在这种模式中,通常每个接收者都包含对另一个接收者的引用。如果一个对象不能处理该请求,那么它会把相同的请求传给下一个接收者,依此类推。

在这里插入图片描述
可以看到责任链模式只有两个角色

  • Handler
    所有处理器类的接口

  • ConcreteHandler x
    具体的处理器类,其实现Handler接口,有多少个处理器,就定义多少个这样的类

二、责任链模式的实现方式

1、基于链表

链表的实现方式比较复杂。如图:
在这里插入图片描述
将传入的第一个HandlerA作为头,然后内部的setHandler方法设置下一个的HandlerB,尾指向HandlerB,当继续有处理器add的时候,将其添加到HandlerB的setHandler方法中,然后尾指向HandlerC,以此类推。

1.1 定义一个抽象处理器类

/**
 * 处理器:子类去处理执行,如果处理完毕则结束;否则,交给下一个处理器执行
 */
public abstract class Handler {
    
    private Handler next = null;
    
    /**
     * 注入子类处理器
     */
    public void setNext(Handler next) {
        this.next= next;
    }
    
    public Handler getNext() throws NullPointerException{
        if (this.next != null) {
        	return this.next;
        } else {
        	throw new NullPointerException("没有设置next!!!请设置在调用");
        }
    }

    /**
     * 抽象方法:由子类个性化实现
     */
    public abstract void handle();
}

1.2 实现这个抽象类。

/**
 * A处理器
 */
public class HandlerA extends Handler {

    @Override
    public void handle() {
        System.out.println("执行A处理器业务逻辑===");
        System.out.println("执行A处理器业务逻辑成功!");
        getNext().handle();
    }
}

/**
 * B处理器
 */
public class HandlerB extends Handler {
    @Override
    public void handle() {
        System.out.println("执行B处理器业务逻辑===");
        System.out.println("执行B处理器业务逻辑成功!");
        getNext().handle();
    }
}

/**
 * C处理器
 */
public class HandlerC extends Handler {
    @Override
    public void handle() {
        System.out.println("执行C处理器业务逻辑===");
        System.out.println("执行C处理器业务逻辑成功!");
        //getNext().handle();
    }
}

1.3 实现一个链表类型的责任链。

/**
 * 责任链:链表
 */
public class HandlerChain extends Handler {

    private Handler head = null; //头
    private Handler tail = null; //尾

    public void addHandler(Handler handler) {
        handler.setNext(null);
        if (null == head) {
        	//第一次添加的时候
            head = handler;
            tail = handler;
        } else{
        	//这一步操作,将尾部的Handler内的成员handler变量赋值为下一个Handler
        	tail.setNext(handler); 
        	tail = handler;
        }
    }

    public void handle() {
        if (null != head) {
            head.handle();
        }
    }
}

1.4 使用(也可以用工厂模式简化使用难度)

public class Test{

    public static void main(String[] args) {
        HandlerChain handler = new HandlerChain();
        handler.addHandler(new HandlerA());
        handler.addHandler(new HandlerB());
        handler.addHandler(new HandlerC());
        handler.handle();
    }
}

2、基于数组

2.1 定义一个抽象处理器类

/**
 * handler的接口
 */
public interface IHandler {

    /**
     * 执行处理
     */
    void handle(IHandler next);
}

2.2 实现这个接口。

/**
 * A处理器
 */
public class HandlerA implements IHandler {
    @Override
    public void handle(IHandler next) {
        System.out.println("执行A处理器=====");
        System.out.println("A处理成功!");
        next.handle();
    }
}

/**
 * B处理器
 */
public class HandlerB implements IHandler {
    @Override
    public void handle(IHandler next) {
        System.out.println("执行B处理器=====");
        System.out.println("B处理成功!");
        next.handle();
    }
}

/**
 * C处理器
 */
public class HandlerC implements IHandler {
	
    @Override
    public void handle(IHandler next) {
        System.out.println("执行C处理器=====");
        System.out.println("C处理成功!");
        next.handle();
    }
}

2.3 实现一个数组类型的责任链。

/**
 * 责任链:数组
 */
public class HandlerChain implements IHandler{

	private List<IHandler> handlers = new ArrayList<>();
	// 有可能出现线程安全问题,要注意
    private int index = 0;

    public HandlerChain addHandler(IHandler handler) {
        handlers.add(handler);
        return this;
    }

	@Override
    public void handle(IHandler next) {
        if (index >= filters.size()) {
        	return;
        }
        MyFilter filter = filters.get(index);
        index++;
        filter.handle(next);
        // 进行回溯,否则没法进行重新过滤了
        index--;                    
    }
}

2.4 使用(也可以用工厂模式简化使用难度)

public class Test{

    public static void main(String[] args) {
        HandlerChain handler = new HandlerChain();
        handler.addHandler(new HandlerA());
        handler.addHandler(new HandlerB());
        handler.addHandler(new HandlerC());
        handler.handle(handler);
    }
}

三、责任链总结

优点

  • 允许动态的增加和删除职责,且由用户决定是否执行某种操作。
  • 实现了被操作对象和操作的解耦。
  • 一个命令可以被多个处理器执行,例如各种框架中的拦截器

缺点

  • 系统复杂度提高,容易出错。即组链时候不合理,可能导致请求得不到执行,还有可能将链变成一个环,请求在里面循环,永远都完不了。
  • 影响性能,出现递归调用,容易造成栈溢出

适用场景

  • 由用户确定实现怎样的处理的流程。
  • 不确定是否需要添加这种处理的情况。
  • 把任务分解,大的任务分解成小步进行处理。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值