温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

C#设计模式之职责链

发布时间:2020-07-16 15:00:00 来源:网络 阅读:833 作者:jinyuan0829 栏目:编程语言

Iron之职责链

需求:

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

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

问题的发现:

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

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     /// <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 /// <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 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     /// <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 /// <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 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     /// <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 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); 6 //执行处理 7 //comModel的一些处理

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

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI