Iron之职责链

需求:

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

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

问题的发现:

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

     /// <summary>
/// 部件
/// </summary>
public class ComponentModel
{
public string Name { get; set; }
public int Value
{
get
{
return ;
}
}
}

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

     /// <summary>
/// 请求的处理类型
/// </summary>
public enum RequestState
{
/// <summary>
/// 检测
/// </summary>
Check,
/// <summary>
/// 设置基础值
/// </summary>
SetDefValue }

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

 /// <summary>
/// 处理请求类1
/// </summary>
public class ConcreteHandlerCaseOne
{
private ComponentModel _comModel;
public ConcreteHandlerCaseOne(ComponentModel comModel)
{
_comModel = comModel;
}
public void HandleRequest(RequestState reqState)
{
switch (reqState)
{
case RequestState.Check:
if (_comModel.Value > )
{
//执行处理
}
break;
case RequestState.SetDefValue:
_comModel.Name = "默认部件";
//执行处理
break;
default: break;
}
}
}
/// <summary>
/// 处理请求类2
/// </summary>
public class ConcreteHandlerCaseTwo
{
private ComponentModel _comModel; public ConcreteHandlerCaseTwo(ComponentModel comModel)
{
_comModel = comModel;
}
public void HandleRequest(RequestState reqState)
{
switch (reqState)
{
case RequestState.Check:
if (_comModel.Value > )
{
//执行处理
}
break;
case RequestState.SetDefValue:
_comModel.Name = "默认部件";
//执行处理
break;
default: break; }
}
}

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

 ComponentModel comModel = new ComponentModel();
ConcreteHandlerCaseOne caseone = new ConcreteHandlerCaseOn(comModel);
caseone.HandleRequest(RequestState.Check);
ConcreteHandlerCaseTwo casetwo = new ConcreteHandlerCaseTw(comModel);
casetwo.HandleRequest(RequestState.Check);

对的,就是这样,一次次的检测下去,如果要检测20次,并且都是不同的实现,那将非常可怕,代码冗余,而且请求调用方和处理方的耦合度也很大,那要怎么样让代码更精简,并且还能有效的解耦,这里就要用到职责链模式。

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

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

设计模式的思想:

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

     /// <summary>
/// 抽象处理者
/// </summary>
public abstract class Handle
{
protected Handle Successor;
public void SetSuccessor(Handle successor)
{
this.Successor = successor;
}
public abstract void HandleRequest(RequestStatereqState,ComponentModel comModel); }

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

 /// <summary>
/// 具体处理者
/// </summary>
public class ConcreteHandlerA : Handle
{
public override void HandleRequest(RequestState reqState, ComponentModel comModel)
{
switch (reqState)
{
case RequestState.Check:
//执行处理 break;
case RequestState.SetDefValue:
//执行处理
break;
default:
this.Successor.HandleRequest(reqState, comModel);
break; }
}
}
/// <summary>
/// 具体处理者
/// </summary>
public class ConcreteHandlerB : Handle
{
public override void HandleRequest(RequestState reqState, ComponentModel comModel)
{
switch (reqState)
{
case RequestState.Check:
//执行处理
break;
case RequestState.SetDefValue:
//执行处理
break;
default:
this.Successor.HandleRequest(reqState, comModel);
break; }
}
}

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

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

 ComponentModel comModel = new ComponentModel();
Handle handlerA = new ConcreteHandlerA();
Handle handlerB = new ConcreteHandlerB();
handlerA.SetSuccessor(handlerB);
handlerA.HandleRequest(RequestState.Check, comModel);

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

看一下中间层的定义:

     /// <summary>
/// ChainOfResponsibility模式帮助类
/// </summary>
public class CORUnit
{
private Handle _Handle; private ComponentModel _ComModel; public CORUnit(ComponentModel commodel)
: this(null, commodel)
{
_ComModel = commodel;
}
public CORUnit(Handle Handle, ComponentModel commodel)
{
_Handle = Handle;
_ComModel = commodel;
}
public void RegisterHandle(Handle handle)
{
if (_Handle != null)
{
_Handle.SetSuccessor(handle);//指向 处理链中的下一个 处理模块
}
else
{
_Handle = handle;
}
}
public void HandleRequest(RequestState reqState)
{
_Handle.HandleRequest(reqState, _ComModel);
}
}

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

 ComponentModel comModel = new ComponentModel();
CORUnit corunit = new CORUnit(comModel);
corunit.RegisterHandle(new ConcreteHandlerA());
corunit.RegisterHandle(new ConcreteHandlerB());
corunit.HandleRequest(RequestState.Check);
//执行处理
//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. java网络编程1

    Socket的构造方法包括: 1.Socket(),无参构造方法: 2.Socket(InetAddress address,int port) throws UnknownHostException ...

  2. Android资源站

    用这个帖子记录下看到的好的android资源站 1.各种资源:http://appxcode.com/ 2.图标 2.1 http://www.easyicon.net 2.2 http://www. ...

  3. three.js全景

    <!DOCTYPE html> <html lang="en"> <head> <title>three.js webgl - eq ...

  4. js接收对象类型数组的服务端、浏览器端实现

    1.服务端 JSONArray jsonArr = JSONUtil.generateObjList(objList); public static generateObjList(List<O ...

  5. [R语言]R语言计算unix timestamp的坑

    R+mongo的组合真是各种坑等着踩 由于mongo中的时间戳普遍使用的是unix timestamp的格式,因此需要对每天的数据进行计算的时候,很容易就想到对timestamp + gap对方式来实 ...

  6. Synchronized同步性与可见性

    Synchronized是具有同步性与可见性的,那么什么是同步性与可见性呢? (1)同步性:同步性就是一个事物要么一起成功,要么一起失败,可谓是有福同享有难同当,就像A有10000去银行转5000给身 ...

  7. linux下的tcp连接超时

    最近需要写一个linux下的通信程序, 通信模块用的是Qt的QTcpSocket. 最后程序需要增加一个断网检测, 在windows下调试没问题, 拔网线, 断网口都能马上检测到, 但到了部署到lin ...

  8. jquery 获取奇数索引的元素

    $(".btn-xs:odd").click(function(){ var $buy_num=$(this).prev("#buy_num").val(); ...

  9. JSON相关知识,转载:删除JSON中数组删除操作

    一:JSON是什么 JSONg格式:对象是一个无序的“名称/值”对的集合. 对象以括号开始,括号结束. 名称冒号分隔值. "名称/值"之间用逗号分隔 例: var people = ...

  10. windows下python的tar.gz文件安装

    windows下下载了django,PIL,web.py发现都是tar.gz格式的文件,网上查找也非常系统的方法,总结一下其他大神的方法,归纳于此. 首先下载tar.gz文件,比如web.py,下载后 ...