关键词搜索

源码搜索 ×
×

设计模式:责任链模式(Chain of Responsibility)

发布2016-04-04浏览5423次

详情内容


欢迎支持笔者新作:《深入理解Kafka:核心设计与实践原理》和《RabbitMQ实战指南》,同时欢迎关注笔者的微信公众号:朱小厮的博客。


欢迎跳转到本文的原文链接:https://honeypps.com/design_pattern/chain-of-responsibility/

 使多个对象都有机会处理请求,从而避免请求的发送者和接受者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递该请求,知道有一个对象处理它为止。
这里写图片描述

责任链模式的角色:

  1. 抽象处理者角色(Handler):定义出一个处理请求的接口。如果需要,接口可以定义出一个方法以设定和返回对下家的引用。这个角色通常由一个Java抽象类或者Java接口实现。上图中Handler类的聚合关系给出了具体子类对下家的引用,抽象方法handlerRequest()规范了子类处理请求的操作。
  2. 具体处理者角色(ConcreteHandler):具体处理者接到请求后,可以选择将请求处理掉,或者将请求传给下家。

 举个简单例子:报销流程,项目经理<部门经理<总经理
 其中项目经理报销额度不能超过1000,部门经理报销额度不能超过5000,超过5000的则需要总经理审核。
1 抽象处理角色ConsumeHandler

public abstract class ConsumeHandler
{
    private ConsumeHandler nextHandler;

    public ConsumeHandler getNextHandler()
    {
        return nextHandler;
    }

    public void setNextHandler(ConsumeHandler nextHandler)
    {
        this.nextHandler = nextHandler;
    }

    public abstract void doHandler(String user, BigDecimal free);
}

    2 具体处理角色

    public class ProjectHandler extends ConsumeHandler
    {
        @Override
        public void doHandler(String user, BigDecimal free)
        {
            if(free.doubleValue() < 1000)
            {
                if(user.equals("jj"))
                    System.out.println(user+"报销不通过");
                else
                    System.out.println(user+"给予报销:"+free);
            }
            else
            {
                if(getNextHandler() != null)
                {
                    getNextHandler().doHandler(user, free);
                }
            }
        }
    }
    
    public class DeptHandler extends ConsumeHandler
    {
        @Override
        public void doHandler(String user, BigDecimal free)
        {
            if(free.doubleValue() < 5000)
            {
                if(user.equals("qq"))
                    System.out.println(user+"报销不通过");
                else
                    System.out.println(user+"给予报销:"+free);
            }
            else
            {
                if(getNextHandler() != null)
                {
                    getNextHandler().doHandler(user, free);
                }
            }
        }
    }
    
    public class GeneralHandler extends ConsumeHandler
    {
        @Override
        public void doHandler(String user, BigDecimal free)
        {
            if(free.doubleValue() >= 5000)
            {
                if(user.equals("zzh"))
                    System.out.println(user+"报销不通过");
                else
                    System.out.println(user+"给予报销:"+free);
            }
            else
            {
                if(getNextHandler() != null)
                {
                    getNextHandler().doHandler(user, free);
                }
            }
        }
    }
    
      17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65

    3 测试代码

            ConsumeHandler project = new ProjectHandler();
            ConsumeHandler dept = new DeptHandler();
            ConsumeHandler general = new GeneralHandler();
            project.setNextHandler(dept);
            dept.setNextHandler(general);
            project.doHandler("jj", new BigDecimal(2000));
            project.doHandler("jj", new BigDecimal(300));
            project.doHandler("qq", new BigDecimal(2000));
            project.doHandler("zzh", new BigDecimal(20000));
            project.doHandler("qq", new BigDecimal(20000));
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    测试结果:

    jj给予报销:2000
    jj报销不通过
    qq报销不通过
    zzh报销不通过
    qq给予报销:20000
    
    • 1
    • 2
    • 3
    • 4
    • 5

     和这个例子相同的还有请假管理,比如请假2天内的部门经理可以处理,超过2天不超过5天的可以研发总监处理,超过5天的需要总经理处理。
     责任链模式可能是一条直线,一个环链甚至一个树结构的一部分。
     责任链模式的缺点:当责任链的链结构比较长比较复杂的话,会产生很多内存垃圾对象,他们在实际处理中,并没有发挥任何的作用。

    JDK中的责任链模式
    java.util.logging.Logger#log()
    javax.servlet.Filter#doFilter()


    参考资料

    1. 23种设计模式
    2. 细数JDK里的设计模式
    3. 重温设计模式(三)——职责链模式(chain of responsibility)

    欢迎跳转到本文的原文链接:https://honeypps.com/design_pattern/chain-of-responsibility/

    欢迎支持笔者新作:《深入理解Kafka:核心设计与实践原理》和《RabbitMQ实战指南》,同时欢迎关注笔者的微信公众号:朱小厮的博客。


    相关技术文章

    点击QQ咨询
    开通会员
    返回顶部
    ×
    微信扫码支付
    微信扫码支付
    确定支付下载
    请使用微信描二维码支付
    ×

    提示信息

    ×

    选择支付方式

    • 微信支付
    • 支付宝付款
    确定支付下载