设计模式11:责任链模式

责任链模式

定义:为了避免请求发送者与接收者耦合在一起,让多个对象都有可能接收请求,将这些对象连接成一条链,并且沿着这条链传递请求,直到有对象处理它为止,这就是责任链模式。

举个栗子咯,当周杰伦要在你的城市开演唱会时,而你恰好有课,这时候咋办呢?总不能不去吧,所以只有向老师请假咯。而请假的话,是有个流程滴,当你提交申请表给辅导员时,如果天数在两天以内的话,辅导员直接给你批准啦,你就可以开溜啦;但是当你请假天数在两天以上,四天以内的时候,辅导员就没那个权力批准啦,它就只能把你的申请表交给学院院长,让院长批准啦;如果天数在四天到七天的话,院长也没法子处理啦,他只有把你的请假申请表交给校长啦;如果请假天数大于七天...抱歉,请假七天那还读个毛的书,一律否决,再附送个叫家长来校大礼包....

用编程语言来实现的话,估计很多人第一想到的就是写一大串if else 语句啦,但在之前讨论策略模式的时候,我们就以及说过了这样的弊端啦,所以我们就要用到我们的责任链模式啦

主要角色

Handler: 抽象处理者。定义了一个处理请求的方法。所有的处理者都必须实现该抽象类。 

ConcreteHandler: 具体处理者。处理它所负责的请求,同时也可以访问它的后继者。如果它能够处理该请求则处理,否则将请求传递到它的后继者。 
Client: 事件的发起者 

实例

首先定义一个假条类

public class LeaveRequest {
	private String name;
	private int leaveDays;
	
	public LeaveRequest(String name, int leaveDays) {
		super();
		this.name = name;
		this.leaveDays = leaveDays;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getLeaveDays() {
		return leaveDays;
	}
	public void setLeaveDays(int leaveDays) {
		this.leaveDays = leaveDays;
	}	
}

定义抽象处理者

public abstract class Leader {
	protected String name;
	protected Leader nextLeader; //责任链上的后继对象
	
	public Leader(String name) {
		super();
		this.name = name;
	}
	
	//设定责任链上的后继对象
	public void setNextLeader(Leader nextLeader) {
		this.nextLeader = nextLeader;
	}
	/**
	 * 处理请求的核心的业务方法
	 * @param request
	 */
	public abstract void handleRequest(LeaveRequest request);
		
}

三个具体的处理者

辅导员

public class Instructor extends Leader{

	public Instructor(String name) {
		super(name);
	
	}
	
	public void handleRequest(LeaveRequest LeaveRequest) {
        if(LeaveRequest.getLeaveDays() <= 2){   //小于2天辅导员审批
            System.out.println("辅导员" + name + "审批" +LeaveRequest.getName() + "同学的请假条,请假天数为" + LeaveRequest.getLeaveDays()+ "天。");
        }
        else{     //否则传递给院长
            if(this.nextLeader != null){
                this.nextLeader.handleRequest(LeaveRequest);
            }
        }
    }

}

院长

public class Dean extends Leader{
	
	public Dean(String name) {
		super(name);
	
	}
	
	public void handleRequest(LeaveRequest LeaveRequest) {
        if(LeaveRequest.getLeaveDays() <= 4){   //小于4天院长审批
            System.out.println("院长" + name + "审批" +LeaveRequest.getName() + "同学的请假条,请假天数为" + LeaveRequest.getLeaveDays()+ "天。");
        }
        else{     //否则传递给校长
            if(this.nextLeader != null){
                this.nextLeader.handleRequest(LeaveRequest);
            }
        }
    }

}

校长

public class President extends Leader{

	public President(String name) {
		super(name);
	
	}
	
	public void handleRequest(LeaveRequest LeaveRequest) {
        if(LeaveRequest.getLeaveDays() <= 7){   //小于7天校长审批
            System.out.println("校长" + name + "审批" +LeaveRequest.getName() + "同学的请假条,请假天数为" + LeaveRequest.getLeaveDays()+ "天。");
        }
        else{
        	System.out.println("叫家长来");
        }
 
    }
}

 客户端测试

public class Client {
	
	public static void main(String[] args) {
		
		
		 Leader instructor = new Instructor("老王");       //辅导员
	     Leader dean = new Dean("老李");      //院长
	     Leader president = new President("老谢");     //校长
	        
	     instructor.setNextLeader(dean);       //辅导员的后续者是院长
	     dean.setNextLeader(president);         //院长的后继者是校长
	     
	     LeaveRequest le = new LeaveRequest("我", 1);
	     instructor.handleRequest(le);
	     
	     le = new LeaveRequest("哥", 3);
	     instructor.handleRequest(le);
	     
	     le = new LeaveRequest("qiu", 5);
	     instructor.handleRequest(le);
	     
	     le = new LeaveRequest("ll", 11);
	     instructor.handleRequest(le);
	}

}

 适用场景

  • 有多个对象可以处理同一个请求,具体哪个对象处理该请求由运行时刻自动确定。
  • 在不明确指定接收者的情况下,向多个对象中的一个提交一个请求。
  • 可动态指定一组对象处理请求。

实际开发中的应用

  • Java中,异常机制就是一种责任链模式。一个try可以对应多个catch,当第一个catch不匹配类型,则自动跳到第二个catch.
  • Javascript语言中,事件的冒泡和捕获机制。Java语言中,事件的处理采用观察者模式。
  • Servlet开发中,过滤器的链式处理

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值