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

来源:互联网 发布:怎么禁用135端口 编辑:程序博客网 时间:2024/06/14 00:08
林炳文Evankaka原创作品。转载请注明出处http://blog.csdn.net/evankaka/article/details/43210027

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

1、简介

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

 2、意图

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

 3、适用性

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

 4、结构

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

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

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


二、使用范例

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

要求提高工资的类

[java] view plain copy
  1. /** 
  2.  
  3. * 文件名:RaiseSalary.java 
  4.  
  5. * 描述:责任链模式讲解 
  6.  
  7. * 创建人:林炳文 
  8.  
  9. * 日 期:2015.1.27 
  10.  
  11. **/  
  12. package RaiseSalary;  
  13.   
  14. /**提高工资的类**/  
  15. public class RaiseSalary {  
  16.     private int num;//要求提高多少工资  
  17.       
  18.     //构造函数,要求提高多少工资  
  19.     public RaiseSalary(int num){  
  20.         this.num=num;  
  21.     }  
  22.     //取得要求提高的工资  
  23.     public int GetNum(){  
  24.         return num;  
  25.           
  26.     }  
  27.     public String toString(){  
  28.         return "[要求提高工资"+num+"元的问题]";  
  29.     }  
  30.   
  31. }  
解决工资问题的抽象类

[java] view plain copy
  1. /** 
  2. * 文件名:Support.java 
  3.  
  4. * 描述:责任链模式讲解 
  5.  
  6. * 创建人:林炳文 
  7.  
  8. * 日 期:2015.1.27 
  9.  
  10. **/  
  11. package Support;  
  12. import RaiseSalary.*;  
  13. /**解决提高工资问题的抽象类**/  
  14. public abstract class Support {  
  15.     private String name;//解决提高工资人的名称  
  16.     private Support next;//问题由下一个人来解决  
  17.       
  18.     //提高工资的解决都  
  19.     public Support(String name){  
  20.         this.name=name;  
  21.     }  
  22.     //设定转送位置  
  23.     public Support SetNext(Support next){  
  24.         this.next=next;  
  25.         return next;      
  26.     }  
  27.     //解决工资问题的步骤  
  28.     public final void GetTrobule(RaiseSalary raisesalary)  
  29.     {  
  30.         if(Resolver(raisesalary)){  
  31.             Succecd(raisesalary);  
  32.         }else if(next!=null){  
  33.             next.GetTrobule(raisesalary);  
  34.         }else{  
  35.           Fail(raisesalary);  
  36.         }  
  37.           
  38.     }  
  39.       
  40.     //打印字符  
  41.     public String toString(){  
  42.           
  43.         return "["+name+"]";  
  44.     }  
  45.     //解决问题的方法  
  46.     protected abstract boolean Resolver(RaiseSalary raisesalary);  
  47.       
  48.   
  49.     //问题解决,工资得到加  
  50.     protected void Succecd(RaiseSalary raisesalary){  
  51.     System.out.println(raisesalary+"由"+this+"解决了。");  
  52.     }  
  53.       
  54.     //问题无法解决,  
  55.     protected void Fail(RaiseSalary raisesalary){  
  56.     System.out.println(raisesalary+"无法解决");  
  57.     }  
  58.       
  59.   
  60. }  
然后就是各种用法了

[java] view plain copy
  1. /** 
  2.  
  3. * 文件名:Main.java 
  4.  
  5. * 描述:责任链模式讲解 
  6.  
  7. * 创建人:林炳文 
  8.  
  9. * 日 期:2015.1.27 
  10.  
  11. **/  
  12. package Main;  
  13. import Support.*;  
  14. import RaiseSalary.*;  
  15.   
  16. /**HR只能搜集要求提高工资的问题,并将它上报**/  
  17. class HR extends Support{  
  18.   
  19.     public HR(String name){  
  20.         super(name);  
  21.     }  
  22.     //HR无法解决要求提高工资的问题  
  23.     @Override  
  24.     protected boolean Resolver(RaiseSalary raisesalary) {  
  25.         // TODO 自动生成的方法存根  
  26.         return false;  
  27.     }  
  28.       
  29. }  
  30. /**组长能处理**/  
  31. class ZuZhang extends Support{  
  32.       
  33.    private int limit;//能提高最大工资的限度  
  34.      
  35.    //构造函数,组长能处理要求提高多少工资的问题  
  36.      public ZuZhang(String name,int limit) {  
  37.        super(name);  
  38.        this.limit=limit;  
  39. }  
  40.        
  41.     @Override  
  42.     protected boolean Resolver(RaiseSalary raisesalary) {  
  43.         if(raisesalary.GetNum()<=limit){  
  44.             return true;  
  45.         }else {  
  46.             return false;  
  47.         }  
  48.     }  
  49.       
  50. }  
  51.   
  52. /**经理能处理问题**/  
  53. class JingLi extends Support{  
  54.       private int limit;//能提高最大工资的限度  
  55.         
  56.    //构造函数,经理能处理要求提高多少工资的问题  
  57.      public JingLi(String name,int limit) {  
  58.        super(name);  
  59.        this.limit=limit;  
  60. }  
  61.     @Override  
  62.     protected boolean Resolver(RaiseSalary raisesalary) {  
  63.         if(raisesalary.GetNum()<=limit){  
  64.             return true;  
  65.         }else {  
  66.             return false;  
  67.         }  
  68.     }  
  69.       
  70. }  
  71.   
  72.   
  73. /**董事长能处理问题**/  
  74. class DongShiZhang extends Support{  
  75.       private int limit;//能提高最大工资的限度  
  76.         
  77.    //构造函数,董事长能处理要求提高多少工资的问题  
  78.      public DongShiZhang(String name,int limit) {  
  79.        super(name);  
  80.        this.limit=limit;  
  81. }  
  82.     @Override  
  83.     protected boolean Resolver(RaiseSalary raisesalary) {  
  84.         if(raisesalary.GetNum()<=limit){  
  85.             return true;  
  86.         }else {  
  87.             return false;  
  88.         }  
  89.     }  
  90.       
  91. }  
  92.   
  93.   
  94. public class Main {  
  95.   
  96.     public static void main(String[] args) {  
  97.           
  98.         Support evan=new HR("人力Evan");  
  99.         Support kaka=new ZuZhang("组长kaka"100);//组长最多能解决提高工资100的问题  
  100.         Support bingbing=new JingLi("经理bingbing"500);//经理最多能解决提高工资500的问题  
  101.         Support wenwen=new DongShiZhang("董事长wenwen"1000);//经理最多能解决提高工资500的问题  
  102.           
  103.         //构成一个责任链  
  104.         evan.SetNext(kaka).SetNext(bingbing).SetNext(wenwen);  
  105.           
  106.         //发生的要滶提高工资的问题  
  107.         for(int i=50;i<1200;i+=50){  
  108.             evan.GetTrobule(new RaiseSalary(i));  
  109.         }  
  110.   
  111.     }  
  112.   
  113. }  

结果输出:

[要求提高工资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

原创粉丝点击