编程模式之十四----行为型----职责链模式

 

 

 定义

   避免把一个请求的发送者和接收者耦合在一起,使多个对象都有机会处理请求。将这个请求的多个接收着连接成一条链,并让请求沿着这个链传递下去,只到有一个结点能处理请求。

  职责链模式中,链形成后,不一定非要有一个结点能够处理请求,也就是说,所有结点都可以处理一下再往下传,也可以都不处理,这样说来就比较灵活了。

 组成

   抽象处理者:AbstractHandler。维护一个对自身类型对象的引用,这个引用作为下一个具体的处理者。声明所有处理者都用到的方法,这个方法的作用是设置本处理者后面的一个处理者。另外声明一个处理请求的方法。

  具体处理者:Handler。实现设置下一个处理者的方法。实现处理请求的方法,也就是业务方法。

 一个例子

   以我们公司的请假过程为例子,我们公司的请假审批过程是这样的:请不多于1天,只用主管(Supervisor)审批就可以了;请不多于3天,而大于1天,就需要部门经理(DepartmentManager)审批;请假超过3天,就需要总经理(GeneralManager)审批了。

  抽象处理者设计为Manager,包含主管,经理和总经理。具体处理者就是上面三位:主管,经理,总经理。这里的请求就是请假这个事。  

  代码如下:

 1     /// <summary>
 2     /// 抽象管理者类
 3     /// </summary>
 4     abstract class Manager
 5     {
 6         //维护下一个管理者的引用
 7         public Manager manager = null;
 8         /// <summary>
 9         /// 设置下一个管理者的方法,也是下一个处理者
10         /// </summary>
11         /// <param name="manager"></param>
12         public abstract void SetNextHandler(Manager manager);
13         /// <summary>
14         /// 业务方法,怎么处理请假这件事
15         /// </summary>
16         public abstract void HandlerLeave(int days);
17     }
18     /// <summary>
19     /// 主管处理者
20     /// </summary>
21     class Supervisor : Manager
22     {
23         public override void SetNextHandler(Manager manager)
24         {
25             this.manager = manager;
26         }
27         public override void HandlerLeave(int days)
28         {
29             if (days <= 1)
30             {
31                 Console.WriteLine("主管处理了请假:允许");
32             }
33             else
34             {
35                 Console.WriteLine("主管没有权力,交给部门经理处理");
36                 this.manager.HandlerLeave(days);
37             }
38         }
39     }
40     /// <summary>
41     /// 部门经理处理者
42     /// </summary>
43     class DepartmentManager : Manager
44     {
45         public override void SetNextHandler(Manager manager)
46         {
47             this.manager = manager;
48         }
49         public override void HandlerLeave(int days)
50         {
51             if (days <= 3)
52             {
53                 Console.WriteLine("部门经理处理了请假:允许");
54             }
55             else
56             {
57                 Console.WriteLine("部门经理没有权力,交给总经理处理");
58                 this.manager.HandlerLeave(days);
59             }
60         }
61     }
62     /// <summary>
63     /// 总经理处理者
64     /// </summary>
65     class GeneralManager : Manager
66     {
67         public override void SetNextHandler(Manager manager)
68         {
69             this.manager = manager;
70         }
71         public override void HandlerLeave(int days)
72         {
73             if (days <= 10)
74             {
75                 Console.WriteLine("总经理处理了请假:允许");
76             }
77             else
78             {
79                 Console.WriteLine("总经理处理了请假:时间太长,不允许");
80             }
81         }
82     }

   客户端代码如下:

 1        static void Main(string[] args)
 2         {
 3             Manager supervisor = new Supervisor();
 4             Manager departManager = new DepartmentManager();
 5             Manager generalManager = new GeneralManager();
 6             //设置主管的下一个处理者:部门经理
 7             supervisor.SetNextHandler(departManager);
 8             //设置总店经理的下一个处理者:总经理
 9             departManager.SetNextHandler(generalManager);
10             //职责链形成,开始处理
11 
12             int days1 = 1;
13             int days2 = 2;
14             int days3 = 3;
15             int days4 = 4;
16             int days5 = 11;
17 
18             supervisor.HandlerLeave(days5);//使用11天测试
19             Console.Read();
20         }

  使用11天测试,结果如下:

主管没有权力,交给部门经理处理
部门经理没有权力,交给总经理处理
总经理处理了请假:时间太长,不允许

  注意:链的创建是由客户端来完成的,客户端有能力改变处理者的处理次序。

 一些扩展

   其实,在上面的例子中,主管和部门经理都做了处理,无论处理的结果是怎么样的,总之是做了处理。这种有叫做不纯的职责链模式

如果主管和部门经理一看时间,只接不批示的话,也就是说不做处理的话,只让大boss处理,又叫做纯的职责链模式

  在实际做程序时,异常处理时,有时会用到以下过程:

1            try
2             {
3             }
4             catch (Exception ex)
5             {
6                 Console.WriteLine(ex.Message);
7                 throw new Exception(ex.Message + "某某处理错误");
8             }

   在第一次捕获异常并显示异常后,又把异常交给下一任"捕捉--处理"过程来二次处理,这种算是不纯的职责链模式。

 使用环境

   不明确请求处理者是具体的哪一个对象,只知道对象是在一个对象群中时,可以使用此模式。

  当有多个对象都有可能处理请求时。

 PS

   做这个笔记的目的是让自己的印象更深一些。写的有些仓促,万望提出宝贵意见,不论是表达方面,还是技能方面或者是文章组织方面。你的意见,对我很重要,谢谢~

 

 

原文地址:https://www.cnblogs.com/ddx-deng/p/3791755.html