一、责任链模式(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.youkuaiyun.com/evankaka/article/details/43210027