首页 > 代码库 > 24天学会设计模式------责任链模式

24天学会设计模式------责任链模式

林炳文Evankaka原创作品。转载请注明出处http://blog.csdn.net/evankaka/article/details/43210027

一、责任链模式(Chain of Responsibility Pattern) 

1、简介

从名字上大概也能猜出这个模式的大概模样——系统中将会存在多个有类似处理能力的对象。当一个请求触发后,请求将在这些对象组成的链条中传递,直到找到最合适的“责任”对象,并进行处理。《设计模式》中给它的定义如下:使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。从定义上可以看出,责任链模式的提出是为了“解耦”,以应变系统需求的变更和不明确性。

 2、意图

使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。

 3、适用性

 有多个的对象可以处理一个请求,哪个对象处理该请求运行时刻自动确定。   你想在不明确指定接收者的情况下,向多个对象中的一个提交一个请求。   
可处理一个请求的对象集合应被动态指定。  

 4、结构

责任链模式涉及到的角色如下所示:

 ●抽象处理者(Handler)角色:定义出一个处理请求的接口。如果需要,接口可以定义 出一个方法以设定和返回对下家的引用。这个角色通常由一个Java抽象类或者Java接口实现。

 ●具体处理者(ConcreteHandler)角色:具体处理者接到请求后,可以选择将请求处理掉,或者将请求传给下家。由于具体处理者持有对下家的引用,因此,如果需要,具体处理者可以访问下家。


二、使用范例

这里举了个加工资的问题,对于不同额度的加工资问题,应由不同级别的领导来解决。HR(无法解决工资问题,它只会向上报告)-》班长-》经理-》董事长

要求提高工资的类

/**

* 文件名:RaiseSalary.java

* 描述:责任链模式讲解

* 创建人:林炳文

* 日 期:2015.1.27

**/
package RaiseSalary;

/**提高工资的类**/
public class RaiseSalary {
	private int num;//要求提高多少工资
	
	//构造函数,要求提高多少工资
	public RaiseSalary(int num){
		this.num=num;
	}
	//取得要求提高的工资
	public int GetNum(){
		return num;
		
	}
	public String toString(){
		return "[要求提高工资"+num+"元的问题]";
	}

}
解决工资问题的抽象类

/**
* 文件名:Support.java

* 描述:责任链模式讲解

* 创建人:林炳文

* 日 期:2015.1.27

**/
package Support;
import RaiseSalary.*;
/**解决提高工资问题的抽象类**/
public abstract class Support {
	private String name;//解决提高工资人的名称
	private Support next;//问题由下一个人来解决
	
	//提高工资的解决都
	public Support(String name){
		this.name=name;
	}
	//设定转送位置
	public Support SetNext(Support next){
		this.next=next;
		return next;	
	}
	//解决工资问题的步骤
	public final void GetTrobule(RaiseSalary raisesalary)
	{
		if(Resolver(raisesalary)){
			Succecd(raisesalary);
		}else if(next!=null){
			next.GetTrobule(raisesalary);
		}else{
		  Fail(raisesalary);
		}
		
	}
	
	//打印字符
	public String toString(){
		
		return "["+name+"]";
	}
	//解决问题的方法
	protected abstract boolean Resolver(RaiseSalary raisesalary);
	

	//问题解决,工资得到加
	protected void Succecd(RaiseSalary raisesalary){
	System.out.println(raisesalary+"由"+this+"解决了。");
	}
	
	//问题无法解决,
	protected void Fail(RaiseSalary raisesalary){
	System.out.println(raisesalary+"无法解决");
	}
	

}
然后就是各种用法了

/**

* 文件名:Main.java

* 描述:责任链模式讲解

* 创建人:林炳文

* 日 期:2015.1.27

**/
package Main;
import Support.*;
import RaiseSalary.*;

/**HR只能搜集要求提高工资的问题,并将它上报**/
class HR extends Support{

	public HR(String name){
		super(name);
	}
	//HR无法解决要求提高工资的问题
	@Override
	protected boolean Resolver(RaiseSalary raisesalary) {
		// TODO 自动生成的方法存根
		return false;
	}
	
}
/**组长能处理**/
class ZuZhang extends Support{
	
   private int limit;//能提高最大工资的限度
   
   //构造函数,组长能处理要求提高多少工资的问题
     public ZuZhang(String name,int limit) {
	   super(name);
	   this.limit=limit;
}
     
	@Override
	protected boolean Resolver(RaiseSalary raisesalary) {
		if(raisesalary.GetNum()<=limit){
			return true;
		}else {
			return false;
		}
	}
	
}

/**经理能处理问题**/
class JingLi extends Support{
      private int limit;//能提高最大工资的限度
      
   //构造函数,经理能处理要求提高多少工资的问题
     public JingLi(String name,int limit) {
	   super(name);
	   this.limit=limit;
}
	@Override
	protected boolean Resolver(RaiseSalary raisesalary) {
		if(raisesalary.GetNum()<=limit){
			return true;
		}else {
			return false;
		}
	}
	
}


/**董事长能处理问题**/
class DongShiZhang extends Support{
      private int limit;//能提高最大工资的限度
      
   //构造函数,董事长能处理要求提高多少工资的问题
     public DongShiZhang(String name,int limit) {
	   super(name);
	   this.limit=limit;
}
	@Override
	protected boolean Resolver(RaiseSalary raisesalary) {
		if(raisesalary.GetNum()<=limit){
			return true;
		}else {
			return false;
		}
	}
	
}


public class Main {

	public static void main(String[] args) {
		
		Support evan=new HR("人力Evan");
		Support kaka=new ZuZhang("组长kaka", 100);//组长最多能解决提高工资100的问题
		Support bingbing=new JingLi("经理bingbing", 500);//经理最多能解决提高工资500的问题
		Support wenwen=new DongShiZhang("董事长wenwen", 1000);//经理最多能解决提高工资500的问题
		
		//构成一个责任链
		evan.SetNext(kaka).SetNext(bingbing).SetNext(wenwen);
		
		//发生的要滶提高工资的问题
		for(int i=50;i<1200;i+=50){
			evan.GetTrobule(new RaiseSalary(i));
		}

	}

}

结果输出:

[要求提高工资50元的问题]由[组长kaka]解决了。
[要求提高工资100元的问题]由[组长kaka]解决了。
[要求提高工资150元的问题]由[经理bingbing]解决了。
[要求提高工资200元的问题]由[经理bingbing]解决了。
[要求提高工资250元的问题]由[经理bingbing]解决了。
[要求提高工资300元的问题]由[经理bingbing]解决了。
[要求提高工资350元的问题]由[经理bingbing]解决了。
[要求提高工资400元的问题]由[经理bingbing]解决了。
[要求提高工资450元的问题]由[经理bingbing]解决了。
[要求提高工资500元的问题]由[经理bingbing]解决了。
[要求提高工资550元的问题]由[董事长wenwen]解决了。
[要求提高工资600元的问题]由[董事长wenwen]解决了。
[要求提高工资650元的问题]由[董事长wenwen]解决了。
[要求提高工资700元的问题]由[董事长wenwen]解决了。
[要求提高工资750元的问题]由[董事长wenwen]解决了。
[要求提高工资800元的问题]由[董事长wenwen]解决了。
[要求提高工资850元的问题]由[董事长wenwen]解决了。
[要求提高工资900元的问题]由[董事长wenwen]解决了。
[要求提高工资950元的问题]由[董事长wenwen]解决了。
[要求提高工资1000元的问题]由[董事长wenwen]解决了。
[要求提高工资1050元的问题]无法解决
[要求提高工资1100元的问题]无法解决
[要求提高工资1150元的问题]无法解决

三、优缺点

1、优点:

 (1)、降低耦合度。它将请求的发送者和接受者解耦。

 (2)、简化了对象。使得对象不需要知道链的结构。

 (3)、增强给对象指派职责的灵活性。通过改变链内的成员或者调动它们的次序,允许动态地新增或者删除责任。

 (4)、增加新的请求处理类很方便。 

2、缺点:

 (1)、不能保证请求一定被接收。

 (2)、系统性能将受到一定影响,而且在进行代码调试时不太方便;可能会造成循环调用。

 (3)、可能不容易观察运行时的特征,有碍于除错。 

林炳文Evankaka原创作品。转载请注明出处http://blog.csdn.net/evankaka/article/details/43210027



24天学会设计模式------责任链模式