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 ;
  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 > )
  17. {
  18. //执行处理
  19. }
  20. break;
  21. case RequestState.SetDefValue:
  22. _comModel.Name = "默认部件";
  23. //执行处理
  24. break;
  25. default:
  26.  
  27. break;
  28. }
  29. }
  30. }
  31. /// <summary>
  32. /// 处理请求类2
  33. /// </summary>
  34. public class ConcreteHandlerCaseTwo
  35. {
  36. private ComponentModel _comModel;
  37.  
  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 > )
  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的一些处理

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

作者:金源

出处:http://www.cnblogs.com/jin-yuan/

本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面

C#设计模式之职责链的更多相关文章

  1. php设计模式之职责链模式

    <?php /** * @desc php设计模式之职责链模式(责任链模式) 定义:顾名思义,责任链模式为请求创建了一个接收者对象的链.这种模式给予请求的类型,对请求的发送者和接收者进行解耦.这 ...

  2. 设计模式之职责链模式(JAVA实现)

    学习netty框架时,看到有人说netty用到了设计模式的职责链模式,学习一下职责链模式,主要参考大话设计模式. 主要场景: 小菜想要加薪,向经理提出加薪请求,经理没有权限,经理交由总监处理,总监也没 ...

  3. 设计模式-利用职责链模式消除if

    本文是对职责链设计模式的应用(变种),所以假设读者已经掌握了职责链设计模式,职责链模式只会应景简介. 本文主要内容: 需求(ShitCode) 职责链模式简介 设计理念 代码演示(消除if) 应用总结 ...

  4. 设计模式:职责链模式(Chain Of Responsibility)

    定  义:使多个对象都有机会处理请求,从而避免请求的发送者和接受者之间的耦合关系.将这些对象连成一条链,并沿着这条链传递请求,直到有一个对象处理它为止. 结构图: 处理请求类: //抽象处理类 abs ...

  5. 设计模式之职责链模式(Chain of Responsibility)摘录

    23种GOF设计模式一般分为三大类:创建型模式.结构型模式.行为模式. 创建型模式抽象了实例化过程,它们帮助一个系统独立于怎样创建.组合和表示它的那些对象.一个类创建型模式使用继承改变被实例化的类,而 ...

  6. TypeScript设计模式之职责链、状态

    看看用TypeScript怎样实现常见的设计模式,顺便复习一下. 学模式最重要的不是记UML,而是知道什么模式可以解决什么样的问题,在做项目时碰到问题可以想到用哪个模式可以解决,UML忘了可以查,思想 ...

  7. Java设计模式之职责链设计模式

    1.什么是-职责链设计模式 责任链模式是一种对象的行为模式.在责任链模式里,很多对象由每一个对象对其下家的引用而连接起来形成一条链.请求在这个链上传递,直到链上的某一个对象决定处理此请求.发出这个请求 ...

  8. 深入理解JavaScript系列(38):设计模式之职责链模式

    介绍 职责链模式(Chain of responsibility)是使多个对象都有机会处理请求,从而避免请求的发送者和接受者之间的耦合关系.将这个对象连成一条链,并沿着这条链传递该请求,直到有一个对象 ...

  9. php实现设计模式之 职责链模式

    <?php /** * 职责链模式 * * 为解除请求的发送者和接收者之间的耦合,而使用多个对象都用机会处理这个请求,将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它 * 抽象 ...

随机推荐

  1. Unreal4教程总结

    一些好的教程分享 Ue4大神的博客 http://www.tomlooman.com 关于CustomDepth的文章的翻译 http://gad.qq.com/program/translatevi ...

  2. linux mysql 安装配置

    1.确认当前linux系统版本,使用以下命令: cat /etc/issue cat /etc/redhat-release 2.下载对应linux系统的mysql安装包. 下载地址:http://d ...

  3. HDU5800 To My Girlfriend(DP)

    题目 Source http://acm.hdu.edu.cn/showproblem.php?pid=5800 Description Dear Guo I never forget the mom ...

  4. 单片机与控制实验(5)——重量测量并在LCD12864显示

    一.实验目的和要求 掌握点阵式液晶显示屏的原理和控制方法,掌握点阵字符的显示方法.掌握模拟/数字(A/D)转换方式,进一步掌握使用C51语言编写程序的方法,使用C51语言编写实现重量测量的功能. 二. ...

  5. clientX .offsetX .screenX x 的区别

    clientX 设置或获取鼠标指针位置相对于当前窗口的 x 坐标,其中客户区域不包括窗口自身的控件和滚动条. clientY 设置或获取鼠标指针位置相对于当前窗口的 y 坐标,其中客户区域不包括窗口自 ...

  6. linux常用命令总结

    du -sh * 当前目录下所有文件占用空间大小,df  空间占用 top 资源使用情况 M 根据驻留内存大小进行排序 tail 1.tail -f filename说明:监视filename文件的尾 ...

  7. http服务的安装与配置

    挂载光盘mount /dev/cdrom /y       #y是挂载光盘的位置 使用yum命令进安装httpd服务 yum命令的配置文件, yum配置文件位于 /etc/yun.repos.d 目录 ...

  8. Struts2的OGNL表达式语言

    一.OGNL的概念 OGNL是Object-Graph Navigation Language的缩写,全称为对象图导航语言,是一种功能强大的表达式语言,它通过简单一致的语法,可以任意存取对象的属性或者 ...

  9. 创建Chrome启动器

    今天清理垃圾时不知怎么把chrome启动器删除了,现在要重新创建一个 1.在桌面创建一个chrome.exe的快捷键方式,属性更改目标为: "C:\Program Files (x86)\G ...

  10. JS中数组的操作[转]

    1.数组的创建 var arrayObj = new Array(); //创建一个数组 var arrayObj = new Array([size]); //创建一个数组并指定长度,注意不是上限, ...