Java设计模式之行为型:责任链模式
职责链可以将请求的处理者组织成一条链,并将请求沿着链传递,如果某个处理者能够处理请求则处理,否则将该请求交由上级处理。客户端只需将请求发送到职责链上,无须关注请求的处理细节,通过职责链将请求的发送者和处理者解耦了,这也是职责链的设计动机。
背景:
学校规定参加校招的同学必须要请假,且要有相关人员的签字,三天以下需辅导员签字、三到七天需要系主任签字,一个星期以上需要院长签字,更多的则需要校长签字!
上图将学生、辅导员、系主任、院长、校长组成了一个简单的链,在这个链上,学生是申请者,其余的都是请求处理者。对于这种将请求一级一级地往上传递直到请求被处理的设计模式就是职责链模式。
一、什么是责任链模式:
职责链可以将请求的处理者组织成一条链,并将请求沿着链传递,如果某个处理者能够处理请求则处理,否则将该请求交由上级处理。客户端只需将请求发送到职责链上,无须关注请求的处理细节,通过职责链将请求的发送者和处理者解耦了,这也是职责链的设计动机。
职责链模式可以简化对象间的相互连接,因为客户端和处理者都没有对方明确的信息,同时处理者也不知道职责链中的结构,处理者只需保存一个指向后续者的引用,而不需要保存所有候选者的引用。
另外职责链模式增加了系统的灵活性,我们可以任意增加或更改处理者,甚至更改处理者的顺序,不过有可能会导致一个请求无论如何也得不到处理,因为它可能被放置在链末端。
所以责任链模式有以下几个优点:
- (1)降低耦合度,将请求的发送者和接收者解耦。反映在代码上就是不需要在类中写很多丑陋的 if….else 语句,如果用了职责链,相当于我们面对一个黑箱,只需将请求递交给其中一个处理者,然后让黑箱内部去负责传递就可以了。
- (2)简化了对象,使得对象不需要链的结构。
- (3)增加系统的灵活性,通过改变链内的成员或者调动他们的次序,允许动态地新增或者删除处理者
- (4)增加新的请求处理类很方便。
但是责任链模式也存在一些缺点:
- (1)不能保证请求一定被成功处理
- (2)系统性能将受到一定影响,并且可能会造成循环调用。
- (3)可能不容易观察运行时的特征,而且在进行代码调试时不太方便,有碍于除错。
二、UML结构图:
- (1)Handler:抽象处理者,定义了一个处理请求的方法。所有的处理者都必须实现该抽象类。
- (2)ConcreteHandler:具体处理者,处理它所负责的请求,同时也可以访问它的后继者,如果它能够处理该请求则处理,否则将请求传递到它的后继者。
- (3)Client: 客户类
下面是最典型的具体处理者类:
public class ConcreteHandler extends Handler
{
public void handleRequest(String request)
{
if(请求request满足条件)
{
...... //处理请求;
}
else
{
this.successor.handleRequest(request); //转发请求
}
}
}
三、代码实现:
我们将使用开头那个请假的实例。请假:3天以下辅导员签字、3到5天系主任签字、6到10天院长签字、11-15天校长签字、15天以上不允签字。
首先是请假条:LeaveNode.java
public class LeaveNode {
/** 请假天数 **/
private int number;
/** 请假人 **/
private String person;
public LeaveNode(String person,int number){
this.person = person;
this.number = number;
}
public int getNumber() {
return number;
}
public void setNumber(int number) {
this.number = number;
}
public String getPerson() {
return person;
}
public void setPerson(String person) {
this.person = person;
}
}
抽象处理者:Leader.java
public abstract class Leader {
/** 姓名 **/
public String name;
/** 后继者 **/
protected Leader successor;
public Leader(String name){
this.name = name;
}
public void setSuccessor(Leader successor) {
this.successor = successor;
}
public abstract void handleRequest(LeaveNode LeaveNode);
}
四个具体处理者:辅导员:Instructor.java
public class Instructor extends Leader{
public Instructor(String name){
super(name);
}
public void handleRequest(LeaveNode LeaveNode) {
if(LeaveNode.getNumber() <= 3){ //小于3天辅导员审批
System.out.println("辅导员" + name + "审批" +LeaveNode.getPerson() + "同学的请假条,请假天数为" + LeaveNode.getNumber() + "天。");
}
else{ //否则传递给系主任
if(this.successor != null){
this.successor.handleRequest(LeaveNode);
}
}
}
}
系主任: DepartmentHead.java
public class DepartmentHead extends Leader{
public DepartmentHead(String name) {
super(name);
}
public void handleRequest(LeaveNode LeaveNode) {
if(LeaveNode.getNumber() <= 7){ //小于7天系主任审批
System.out.println("系主任" + name + "审批" +LeaveNode.getPerson() + "同学的请假条,请假天数为" + LeaveNode.getNumber() + "天。");
}
else{ //否则传递给院长
if(this.successor != null){
this.successor.handleRequest(LeaveNode);
}
}
}
}
院长:Dean.java
public class Dean extends Leader{
public Dean(String name) {
super(name);
}
public void handleRequest(LeaveNode LeaveNode) {
if(LeaveNode.getNumber() <= 10){ //小于10天院长审批
System.out.println("院长" + name + "审批" +LeaveNode.getPerson() + "同学的请假条,请假天数为" + LeaveNode.getNumber() + "天。");
}
else{ //否则传递给校长
if(this.successor != null){
this.successor.handleRequest(LeaveNode);
}
}
}
}
校长:President.java
public class President extends Leader{
public President(String name) {
super(name);
}
public void handleRequest(LeaveNode LeaveNode) {
if(LeaveNode.getNumber() <= 15){ //小于15天校长长审批
System.out.println("校长" + name + "审批" +LeaveNode.getPerson() + "同学的请假条,请假天数为" + LeaveNode.getNumber() + "天。");
}
else{ //否则不允批准
System.out.println("请假天天超过15天,不批准...");
}
}
}
客户端:Client.java
public class Client {
public static void main(String[] args) {
Leader instructor = new Instructor("陈毅"); //辅导员
Leader departmentHead = new DepartmentHead("王明"); //系主任
Leader dean = new Dean("张强"); //院长
Leader president = new President("王晗"); //校长
instructor.setSuccessor(departmentHead); //辅导员的后续者是系主任
departmentHead.setSuccessor(dean); //系主任的后续者是院长
dean.setSuccessor(president); //院长的后续者是校长
//请假3天的请假条
LeaveNode leaveNode1 = new LeaveNode("张三", 3);
instructor.handleRequest(leaveNode1);
//请假9天的请假条
LeaveNode leaveNode2 = new LeaveNode("李四", 9);
instructor.handleRequest(leaveNode2);
//请假15天的请假条
LeaveNode leaveNode3 = new LeaveNode("王五", 15);
instructor.handleRequest(leaveNode3);
//请假20天的请假条
LeaveNode leaveNode4 = new LeaveNode("赵六", 20);
instructor.handleRequest(leaveNode4);
}
}
运行结果:
四、纯的与不纯的责任链模式:
(1)纯的责任链模式要求处理者对象只能在两个行为中选择一个:一是承担责任,二是把责任推给下家,不允许出现某一个具体处理者对象在承担了一部分责任后又把责任向下传的情况。
(2)在纯的责任链模式里面,请求必须被某一个处理者对象所接收;在不纯的责任链模式里面,一个请求可以最终不被任何接收端对象所接收。
设计模式系列文章:
更多推荐
所有评论(0)