`

责任链设计模式chainOfResponsibility

阅读更多
问题引人:申请聚餐费用,申请人填写申请单,然后交给领导审阅,如果申请批准下来,领导会通知申请人,然后申请人去财务领费用,如果没有就罢了。项目经理、部门经理、总经理审批的费用额度不同。一般申请人并不知道到底是由谁来处理他的请求。
项目经理-》部门经理->总经理,也可能是部门经理->总经理,责任链是变化的。
不使用设计模式的解决方式:
package notusingMode;

public class FeeRequest {
//提交申请给部门经理
	public String requestToProjectManager(String user,double fee){
		String str = "";
		if(fee<500){
			str = this.projectHandle(user,fee);
		}
		else if(fee<1000){
			str = this.deptManagerHandle(user,fee);
		}
		else if(fee>=1000){
			str = this.generalManagerHandle(user,fee);
		}
		return str;
	}

	private String generalManagerHandle(String user, double fee) {
		String str = "";
		if("小李".equals(user)){
			str="总经理同意"+user+"聚餐费用"+fee+"元的请求";
		}
		else {
			str ="总经理不同意"+user+"聚餐费用"+fee+"元的请求";
		}
		return str;
	}

	private String deptManagerHandle(String user, double fee) {

		String str = "";
		if("小李".equals(user)){
			str="部门经理同意"+user+"聚餐费用"+fee+"元的请求";
		}
		else {
			str ="部门经理不同意"+user+"聚餐费用"+fee+"元的请求";
		}
		return str;
	}

	private String projectHandle(String user, double fee) {

		String str = "";
		if("小李".equals(user)){
			str="项目经理同意"+user+"聚餐费用"+fee+"元的请求";
		}
		else {
			str ="项目经理不同意"+user+"聚餐费用"+fee+"元的请求";
		}
		return str;
	}
	
}

package notusingMode;

public class Client {

	public static void main(String[] args) {

		FeeRequest request = new FeeRequest();
		String ret1 = request.requestToProjectManager("小李", 300);
	}

}


问题抽象:客户端发出一个请求,会有很多对象都可以来处理这个请求,而且不同对象的处理逻辑是不一样的。对于客户端而言,无所谓谁来处理。还希望处理流程是可以灵活
变动的,而处理请求的对象需要能方便地修改或者被替换掉,以适应新的业务功能的需要。如何?=---》责任链模式
定义:使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这些对象连成一个链,并沿着这条链传递该请求,直到有一个对象处理它为止。
结构
Handler:定义职责的接口,通常在这里定义处理请求的方法,可以在这里实现后继链
ConcreteHandler:实现职责的类,在这个类中,实现对在它职责范围内请求的处理,如果不处理就转发请求给后继者。
Client:职责链的客户端,向链上的具体处理对象提交请求,让责任链负责处理。
package chainOfResponsibility;

public abstract class Handler {

	protected Handler successor; // 后继者
	
	public void setSuccessor(Handler successor) {
		this.successor = successor;
	}

	public abstract void handleRequest();
}


package chainOfResponsibility;

public class ConcreteHandler1 extends Handler {

	@Override
	public void handleRequest() {

		boolean someCondition = false;
		
		if(someCondition){
			//如果属于自己职责范围,就在这里处理请求
			System.out.println("ConcreteHandler1 handle request");
		}
		else{//不属于自己职责范围,就转发给后继的职责对象
			
			if(this.successor!=null){
				this.successor.handleRequest();
			}
		}
	}

}

package chainOfResponsibility;

public class ConcreteHandler2 extends Handler {

	@Override
	public void handleRequest() {

		boolean someCondition = false;
		
		if(someCondition){
			//如果属于自己职责范围,就在这里处理请求
			System.out.println("ConcreteHandler2 handle request");
		}
		else{//不属于自己职责范围,就转发给后继的职责对象
			
			if(this.successor!=null){
				this.successor.handleRequest();
			}
		}
	}

}

package chainOfResponsibility;

public class Client {

	public static void main(String[] args) {
		// 先组装责任链
		Handler h1 = new ConcreteHandler1();
		Handler h2 = new ConcreteHandler2();
		
		h1.setSuccessor(h2); 
		
		//然后提交请求
		h1.handleRequest();

	}

}


package chainOfResponsibilitySolve;

public abstract class Handler {

	protected Handler successor; // 后继者
	
	public void setSuccessor(Handler successor) {
		this.successor = successor;
	}

	public abstract String handleFeeRequest(String user,double fee);
}

使用责任链设计模式解决上述的费用请求问题:
package chainOfResponsibilitySolve;

public class ProjectManager extends Handler {
	String str = "";

	@Override
	public String handleFeeRequest(String user, double fee) {
		if(fee<500){
			if("小李".equals(user)){
				str="项目经理同意"+user+"聚餐费用"+fee+"元的请求";
			}
			else {
				str="项目经理不同意"+user+"聚餐费用"+fee+"元的请求";
			}
			return str;
		}
		else{
			//超过500,继续传递给级别更高的人来处理
			if(this.successor!=null){
				return successor.handleFeeRequest(user, fee);
			}
			
		}
		return str;
	}
	

}


package chainOfResponsibilitySolve;

public class DeptManager extends Handler {
	String str = "";

	@Override
	public String handleFeeRequest(String user, double fee) {
		if(fee<1000){
			if("小李".equals(user)){
				str="部门经理同意"+user+"聚餐费用"+fee+"元的请求";
			}
			else {
				str="部门经理不同意"+user+"聚餐费用"+fee+"元的请求";
			}
			return str;
		}
		else{
			//超过500,继续传递给级别更高的人来处理
			if(this.successor!=null){
				return successor.handleFeeRequest(user, fee);
			}
			
		}
		return str;
	}
}



package chainOfResponsibilitySolve;

public class GeneralManager extends Handler {
	String str = "";

	@Override
	public String handleFeeRequest(String user, double fee) {
		if(fee>=1000){
			if("小李".equals(user)){
				str="总经理同意"+user+"聚餐费用"+fee+"元的请求";
			}
			else {
				str="总经理不同意"+user+"聚餐费用"+fee+"元的请求";
			}
			return str;
		}
		else{
			//超过500,继续传递给级别更高的人来处理
			if(this.successor!=null){
				return successor.handleFeeRequest(user, fee);
			}
			
		}
		return str;
	}
	

}

package chainOfResponsibilitySolve;

public class Client {

	public static void main(String[] args) {
		// 先组装责任链
		Handler h1 = new ProjectManager();
		Handler h2 = new DeptManager();
		Handler h3 = new GeneralManager();
		
		h1.setSuccessor(h2);
		h2.setSuccessor(h3);
		
		//然后提交请求
		h1.handleFeeRequest("张三",300);

	}

}

处理多个请求的应用如包multipleRequest,但是有一个问题是,只要增加一个业务,就需要修改职责的接口,这是很不灵活的,java开发中很强调面向接口编程,因此接口应该相对保持稳定。
modifyMultipleRequest


功能链,如过滤器,在业务逻辑处理之前,进行权限检查,通用数据校验,数据逻辑校验等处理如销售信息保存的应用如sales





















分享到:
评论
1 楼 xlsky0713 2011-12-08  
为什么不把 “申请就餐” 这个业务抽象出来
可以建一个业务接口类 如 abstract class apply
定义抽象方法 excute()

把handleFeeRequest 参数换为 apply

根据apply 类型 判断是handler 还是直接指向那个 excute 方法

这样业务变更后 我们只需要修改 实现类的 excute 方法就可以了

相关推荐

Global site tag (gtag.js) - Google Analytics