使多个对象都有机会处理请求,从而避免请求的发送者和接受者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递该请求,知道有一个对象处理它为止。
责任链模式的角色: 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);
}
}
}
}
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 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 ));
测试结果:
jj给予报销:2000
jj报销不通过
qq报销不通过
zzh报销不通过
qq给予报销:20000
和这个例子相同的还有请假管理,比如请假2天内的部门经理可以处理,超过2天不超过5天的可以研发总监处理,超过5天的需要总经理处理。 责任链模式可能是一条直线,一个环链甚至一个树结构的一部分。 责任链模式的缺点:当责任链的链结构比较长比较复杂的话,会产生很多内存垃圾对象,他们在实际处理中,并没有发挥任何的作用。
JDK中的责任链模式 java.util.logging.Logger#log() javax.servlet.Filter#doFilter()
参考资料 1. 《23种设计模式 》 2. 《细数JDK里的设计模式 》 3. 《重温设计模式(三)——职责链模式(chain of responsibility) 》