职责链模式——使多个对象都有可能处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这个对象连成一条链,并沿着这条链传递请求,知道有一个对象处理它为止。
抽象处理者角色(Handler):
定义一个处理请求的接口,定义一个方法以设定和返回对下一个处理角色的引用。
具体处理者角色(ConcreteHandler):
具体处理者接收到请求时,可以选择将请求处理掉,或者将请求传给下家。由于具体处理者持有下家,如必要具体处理者可以访问下家。
代码结构:
抽象处理者角色——
package com.hy.chain;
public abstract class Handler {
/**
* 持有后继的责任对象
*/
protected Handler successor;
/**
* 示意处理请求的方法,虽然这个示意方法是没有传入参数的
* 但实际是可以传入参数的,根据具体需要来选择是否传递参数
*/
public abstract void handleRequest();
/**
* 取值方法
*/
public Handler getSuccessor() {
return successor;
}
/**
* 赋值方法,设置后继的责任对象
*/
public void setSuccessor(Handler successor) {
this.successor = successor;
}
}
具体的处理者角色———
package com.hy.chain;
public class ConcreteHandler1 extends Handler {
/**
* 处理方法,调用此方法处理请求
*/
@Override
public void handleRequest() {
/**
* 判断是否有后继的责任对象
* 如果有,就转发请求给后继的责任对象
* 如果没有,则处理请求
*/
if(getSuccessor() != null)
{
System.out.println("1放过请求");
getSuccessor().handleRequest();
}else
{
System.out.println("1处理请求");
}
}
}
package com.hy.chain;
public class ConcreteHandler2 extends Handler {
/**
* 处理方法,调用此方法处理请求
*/
@Override
public void handleRequest() {
/**
* 判断是否有后继的责任对象
* 如果有,就转发请求给后继的责任对象
* 如果没有,则处理请求
*/
if(getSuccessor() != null)
{
System.out.println("2放过请求");
getSuccessor().handleRequest();
}else
{
System.out.println("2处理请求");
}
}
}
测试类————
package com.hy.chain;
public class Client {
public static void main(String[] args) {
//组装责任链
Handler handler1 = new ConcreteHandler1();
Handler handler2 = new ConcreteHandler2();
handler1.setSuccessor(handler2);
//提交请求
handler1.handleRequest();
}
}
客户端创建了两个处理者对象,并指定第一个处理者对象的继承者是第二个处理者对象,第二个对象没有继承者。
本例中的逻辑比较简单,有继承者就由继承者处理,否则自行处理。
以部门聚餐,申请聚餐费用为例:
不同级别的领导可以审批不同的额度。项目经理审批500元以内的,部门经理审批1000元以内的,总监审批任意额度的申请。
当申请人发起请求时,请求会被项目经理,部门经理和总监中的某一位来审批,但是他并不知道具体是谁审批。申请人一般是提交请求给项目经理,剩下的流程不需要关心。
抽象处理者角色类:
public abstract class Handler {
/**
* 持有下一个处理请求的对象
*/
protected Handler successor = null;
/**
* 取值方法
*/
public Handler getSuccessor() {
return successor;
}
/**
* 设置下一个处理请求的对象
*/
public void setSuccessor(Handler successor) {
this.successor = successor;
}
/**
* 处理聚餐费用的申请
* @param user 申请人
* @param fee 申请的钱数
* @return 成功或失败的具体通知
*/
public abstract String handleFeeRequest(String user , double fee);
}
具体处理者角色:
项目经理------
public class ProjectManager extends Handler {
@Override
public String handleFeeRequest(String user, double fee) {
String str = "";
//项目经理权限比较小,只能在500以内
if(fee < 500)
{
//为了测试,简单点,只同意张三的请求
if("张三".equals(user))
{
str = "成功:项目经理同意【" + user + "】的聚餐费用,金额为" + fee + "元";
}else
{
//其他人一律不同意
str = "失败:项目经理不同意【" + user + "】的聚餐费用,金额为" + fee + "元";
}
}else
{
//超过500,继续传递给级别更高的人处理
if(getSuccessor() != null)
{
return getSuccessor().handleFeeRequest(user, fee);
}
}
return str;
}
}
部门经理
public class DeptManager extends Handler {
@Override
public String handleFeeRequest(String user, double fee) {
String str = "";
//部门经理的权限只能在1000以内
if(fee < 1000)
{
//为了测试,简单点,只同意张三的请求
if("张三".equals(user))
{
str = "成功:部门经理同意【" + user + "】的聚餐费用,金额为" + fee + "元";
}else
{
//其他人一律不同意
str = "失败:部门经理不同意【" + user + "】的聚餐费用,金额为" + fee + "元";
}
}else
{
//超过1000,继续传递给级别更高的人处理
if(getSuccessor() != null)
{
return getSuccessor().handleFeeRequest(user, fee);
}
}
return str;
}
}
总监:
public class GeneralManager extends Handler {
@Override
public String handleFeeRequest(String user, double fee) {
String str = "";
//总经理的权限很大,只要请求到了这里,他都可以处理
if(fee >= 1000)
{
//为了测试,简单点,只同意张三的请求
if("张三".equals(user))
{
str = "成功:总经理同意【" + user + "】的聚餐费用,金额为" + fee + "元";
}else
{
//其他人一律不同意
str = "失败:总经理不同意【" + user + "】的聚餐费用,金额为" + fee + "元";
}
}else
{
//如果还有后继的处理对象,继续传递
if(getSuccessor() != null)
{
return getSuccessor().handleFeeRequest(user, fee);
}
}
return str;
}
}
客户端测试类:
public class Client {
public static void main(String[] args) {
//先要组装责任链
Handler h1 = new GeneralManager();
Handler h2 = new DeptManager();
Handler h3 = new ProjectManager();
h3.setSuccessor(h2);
h2.setSuccessor(h1);
//开始测试
String test1 = h3.handleFeeRequest("张三", 300);
System.out.println("test1 = " + test1);
String test2 = h3.handleFeeRequest("李四", 300);
System.out.println("test2 = " + test2);
System.out.println("---------------------------------------");
String test3 = h3.handleFeeRequest("张三", 700);
System.out.println("test3 = " + test3);
String test4 = h3.handleFeeRequest("李四", 700);
System.out.println("test4 = " + test4);
System.out.println("---------------------------------------");
String test5 = h3.handleFeeRequest("张三", 1500);
System.out.println("test5 = " + test5);
String test6 = h3.handleFeeRequest("李四", 1500);
System.out.println("test6 = " + test6);
}
}
职责链模式可以灵活的改变内部的传递规则,每个人可以动态的制定自己的继承者。
如果初始层级暂时不在或消失,请求也可以直接发送给其他层级,后续职责链还会继续进行。而且可以随时增加和修改处理一个请求的结构,增加了给对象指派的职责的灵活性。
如果不用职责链,申请者需要和公司的每一层都发生耦合关系,代码里也会增加过多的if…else 语句。使用之后,我们只需要认识其中的一个部门,让职责链进行内部的职责传递。
需要注意的是,一个请求极有可能到了链的末端都得不到处理,或者因为没有正确配置而得不到处理,需要事先考虑全面。
重要的有两点,一是事先给每个具体管理者设置后继者,二是每个具体的管理者处理请求时,要有严格的界限判断------是处理请求还是交给后继者处理。
共同学习,写下你的评论
评论加载中...
作者其他优质文章