C#设计模式之职责链

简介:

Iron之职责链

需求:

"Iron"的建造一直没有停止,现在单个部件是有的,但是在部件从工厂里出来的时候,在组装到一起之前,我们还是非常有必要对部件进行质量检测,或者是其它个方面的检测,又或者是设置部件标识信息等等,这些操作可以是有序的(也可以是无序的)。

现在为了实现上面的所讲的功能来进行演示,然过程中会发现问题,然后解决问题。这里不多说了直接进入主题。

问题的发现:

首先我定义了一个ComponentModel类,它是要被检验的对象

1
2
3
4
5
6
7
8
9
10
11
12
13
14
1      /// <summary>
2      /// 部件
3      /// </summary>
4      public  class  ComponentModel
5     {
6          public  string  Name {  get set ; }
7          public  int  Value
8         {
9              get
10             {
11                  return  5;
12             }
13         }
14     }

这里先定义了一个请求处理类型的枚举,下面要用到,这样比用什么字符串或者是数字来作条件判断要好很多。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
1      /// <summary>
2      /// 请求的处理类型
3     /// </summary>
4      public  enum  RequestState
5     {
6          /// <summary>
7          /// 检测
8          /// </summary>
9         Check,
10          /// <summary>
11          /// 设置基础值
12          /// </summary>
13         SetDefValue
14
15     }

再然后,我们再来定义检验ComponentModel类的类型:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
/// <summary>
2      /// 处理请求类1
3      /// </summary>
4      public  class  ConcreteHandlerCaseOne
5     {
6          private  ComponentModel _comModel;
7          public  ConcreteHandlerCaseOne(ComponentModel comModel)
8         {
9             _comModel = comModel;
10         }
11          public  void  HandleRequest(RequestState reqState)
12         {
13              switch  (reqState)
14             {
15                  case  RequestState.Check:
16                      if  (_comModel.Value > 5)
17                     {
18                      //执行处理
19                     }
20                      break ;
21                  case  RequestState.SetDefValue:
22                     _comModel.Name =  "默认部件" ;
23                      //执行处理
24                      break ;
25                  default :
26
27                      break ;
28             }
30         }
31     }
32      /// <summary>
33      /// 处理请求类2
34      /// </summary>
35      public  class  ConcreteHandlerCaseTwo
36     {
37          private  ComponentModel _comModel;
38          public  ConcreteHandlerCaseTwo(ComponentModel comModel)
39         {
40             _comModel = comModel;
41         }
42          public  void  HandleRequest(RequestState reqState)
43         {
44              switch  (reqState)
45             {
46                  case  RequestState.Check:
47                      if  (_comModel.Value > 5)
48                     {
49                          //执行处理
50                     }
51                      break ;
52                  case  RequestState.SetDefValue:
53                     _comModel.Name =  "默认部件" ;
54                      //执行处理
55                      break ;
56                  default :
57
58                      break ;
59
60             }
61         }
62     }

定义了两个类型,ConcreteHandlerCaseOne和ConcreteHandlerCaseTwo两个类型,都是用来处理检测ComponentModel类型的,现在这些类型都齐全了我们来检测一下吧。

1
2
3
4
5
1 ComponentModel comModel =  new  ComponentModel();
2 ConcreteHandlerCaseOne caseone =  new  ConcreteHandlerCaseOn(comModel);
3 caseone.HandleRequest(RequestState.Check);
4 ConcreteHandlerCaseTwo casetwo =  new  ConcreteHandlerCaseTw(comModel);
5 casetwo.HandleRequest(RequestState.Check);
对的,就是这样,一次次的检测下去,如果要检测20次,并且都是不同的实现,那将非常可怕,代码冗余,而且请求调用方和处理方的耦合度也很大,那要怎么样让代码更精简,并且还能有效的解耦,这里就要用到职责链模式。

 

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

这里要强调一下的是本篇的示例中并没有完全遵从设计模式的定义,还是按照本文开始的功能需求来做的设计,当然了模式的核心不变。

设计模式的思想:

现在先对处理方进行抽象:


1
2
3
4
5
6
7
8
9
10
11
12
13
1      /// <summary>
2      /// 抽象处理者
3     /// </summary>
4      public  abstract  class  Handle
5     {
6          protected  Handle Successor;
7          public  void  SetSuccessor(Handle successor)
8         {
9              this .Successor = successor;
10         }
11          public  abstract  void  HandleRequest(RequestStatereqState,ComponentModel comModel);
12
13     }

既然有了抽象,那就得有具体的实现:


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
/// <summary>
2      /// 具体处理者
3      /// </summary>
4      public  class  ConcreteHandlerA : Handle
5     {
6          public  override  void  HandleRequest(RequestState reqState, ComponentModel comModel)
7         {
8              switch  (reqState)
9             {
10                  case  RequestState.Check:
11                      //执行处理
12
13                      break ;
14                  case  RequestState.SetDefValue:
15                      //执行处理
16                      break ;
17                  default :
18                      this .Successor.HandleRequest(reqState, comModel);
19                      break ;
20
21             }
22         }
23     }
24      /// <summary>
25      /// 具体处理者
26      /// </summary>
27      public  class  ConcreteHandlerB : Handle
28     {
29          public  override  void  HandleRequest(RequestState reqState, ComponentModel comModel)
30         {
31              switch  (reqState)
32             {
33                  case  RequestState.Check:
34                      //执行处理
35                      break ;
36                  case  RequestState.SetDefValue:
37                      //执行处理
38                      break ;
39                  default :
40                      this .Successor.HandleRequest(reqState, comModel);
41                      break ;
42
43             }
44         }
45     }

这里的类型应该只定义一个的是为了让大家看的更明白。

在这里看抽象处理者Handle类型,它里面有个protected级别的变量Successor,Successor呢就代表着链表中每一环的指针,指向谁呢?当然是指向下一个处理者。
现在来看一下调用的代码:

1
2
3
4
5
1 ComponentModel comModel =  new  ComponentModel();
2 Handle handlerA =  new  ConcreteHandlerA();
3 Handle handlerB =  new  ConcreteHandlerB();
4 handlerA.SetSuccessor(handlerB);
5 handlerA.HandleRequest(RequestState.Check, comModel);

看上去已经不错了,耦合度还是很大的,对于handlerA的调用,还是再调用方直接调用的,这时需要一个中间层,

看一下中间层的定义:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
1      /// <summary>
2      /// ChainOfResponsibility模式帮助类
3     /// </summary>
4      public  class  CORUnit
5     {
6          private  Handle _Handle;
7
8          private  ComponentModel _ComModel;
9
10          public  CORUnit(ComponentModel commodel)
11             :  this ( null , commodel)
12         {
13             _ComModel = commodel;
14         }
15          public  CORUnit(Handle Handle, ComponentModel commodel)
16         {
17             _Handle = Handle;
18             _ComModel = commodel;
19         }
20          public  void  RegisterHandle(Handle handle)
21         {
22              if  (_Handle !=  null )
23             {
24                 _Handle.SetSuccessor(handle); //指向 处理链中的下一个 处理模块
25             }
26              else
27             {
28                 _Handle = handle;
29             }
30         }
31          public  void  HandleRequest(RequestState reqState)
32         {
33             _Handle.HandleRequest(reqState, _ComModel);
34         }
35     }

通过加了一层,再来看一下调用方的代码:


1
2
3
4
5
6
7
1 ComponentModel comModel =  new  ComponentModel();
2 CORUnit corunit =  new  CORUnit(comModel);
3 corunit.RegisterHandle( new  ConcreteHandlerA());
4 corunit.RegisterHandle( new  ConcreteHandlerB());
5 corunit.HandleRequest(RequestState.Check);
//执行处理
//comModel的一些处理

是不是感觉调用方,跟实际的处理方之间的关系变得很弱了,这样目的也就达到了。




     本文转自jinyuan0829 51CTO博客,原文链接:http://blog.51cto.com/jinyuan/1409124,如需转载请自行联系原作者



相关文章
|
6月前
|
设计模式 Java 应用服务中间件
【设计模式——学习笔记】23种设计模式——职责链/责任链模式(Chain of Responsibility)(原理讲解+应用场景介绍+案例介绍+Java代码实现)
【设计模式——学习笔记】23种设计模式——职责链/责任链模式(Chain of Responsibility)(原理讲解+应用场景介绍+案例介绍+Java代码实现)
75 0
|
9月前
|
设计模式
设计模式-职责链+反射
设计模式-职责链+反射
36 0
|
应用服务中间件 容器 设计模式
|
10天前
|
设计模式 SQL 算法
设计模式了解哪些,模版模式
设计模式了解哪些,模版模式
19 0
|
29天前
|
设计模式 Java uml
C++设计模式之 依赖注入模式探索
C++设计模式之 依赖注入模式探索
37 0
|
3月前
|
设计模式 存储 算法
Java 设计模式最佳实践:三、行为模式
Java 设计模式最佳实践:三、行为模式
|
2月前
|
设计模式 前端开发 JavaScript
观察者模式 vs 发布-订阅模式:两种设计模式的对决!
欢迎来到前端入门之旅!这个专栏是为那些对Web开发感兴趣、刚刚开始学习前端的读者们打造的。无论你是初学者还是有一些基础的开发者,我们都会在这里为你提供一个系统而又亲切的学习平台。我们以问答形式更新,为大家呈现精选的前端知识点和最佳实践。通过深入浅出的解释概念,并提供实际案例和练习,让你逐步建立起一个扎实的基础。无论是HTML、CSS、JavaScript还是最新的前端框架和工具,我们都将为你提供丰富的内容和实用技巧,帮助你更好地理解并运用前端开发中的各种技术。
|
7天前
|
设计模式 Java 数据库
小谈设计模式(2)—简单工厂模式
小谈设计模式(2)—简单工厂模式
|
7天前
|
设计模式 Java
小谈设计模式(9)—工厂方法模式
小谈设计模式(9)—工厂方法模式