C#设计模式之职责链
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的一些处理
是不是感觉调用方,跟实际的处理方之间的关系变得很弱了,这样目的也就达到了。
C#设计模式之职责链的更多相关文章
- php设计模式之职责链模式
<?php /** * @desc php设计模式之职责链模式(责任链模式) 定义:顾名思义,责任链模式为请求创建了一个接收者对象的链.这种模式给予请求的类型,对请求的发送者和接收者进行解耦.这 ...
- 设计模式之职责链模式(JAVA实现)
学习netty框架时,看到有人说netty用到了设计模式的职责链模式,学习一下职责链模式,主要参考大话设计模式. 主要场景: 小菜想要加薪,向经理提出加薪请求,经理没有权限,经理交由总监处理,总监也没 ...
- 设计模式-利用职责链模式消除if
本文是对职责链设计模式的应用(变种),所以假设读者已经掌握了职责链设计模式,职责链模式只会应景简介. 本文主要内容: 需求(ShitCode) 职责链模式简介 设计理念 代码演示(消除if) 应用总结 ...
- 设计模式:职责链模式(Chain Of Responsibility)
定 义:使多个对象都有机会处理请求,从而避免请求的发送者和接受者之间的耦合关系.将这些对象连成一条链,并沿着这条链传递请求,直到有一个对象处理它为止. 结构图: 处理请求类: //抽象处理类 abs ...
- 设计模式之职责链模式(Chain of Responsibility)摘录
23种GOF设计模式一般分为三大类:创建型模式.结构型模式.行为模式. 创建型模式抽象了实例化过程,它们帮助一个系统独立于怎样创建.组合和表示它的那些对象.一个类创建型模式使用继承改变被实例化的类,而 ...
- TypeScript设计模式之职责链、状态
看看用TypeScript怎样实现常见的设计模式,顺便复习一下. 学模式最重要的不是记UML,而是知道什么模式可以解决什么样的问题,在做项目时碰到问题可以想到用哪个模式可以解决,UML忘了可以查,思想 ...
- Java设计模式之职责链设计模式
1.什么是-职责链设计模式 责任链模式是一种对象的行为模式.在责任链模式里,很多对象由每一个对象对其下家的引用而连接起来形成一条链.请求在这个链上传递,直到链上的某一个对象决定处理此请求.发出这个请求 ...
- 深入理解JavaScript系列(38):设计模式之职责链模式
介绍 职责链模式(Chain of responsibility)是使多个对象都有机会处理请求,从而避免请求的发送者和接受者之间的耦合关系.将这个对象连成一条链,并沿着这条链传递该请求,直到有一个对象 ...
- php实现设计模式之 职责链模式
<?php /** * 职责链模式 * * 为解除请求的发送者和接收者之间的耦合,而使用多个对象都用机会处理这个请求,将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它 * 抽象 ...
随机推荐
- PL/SQL客户端中执行insert语句,插入中文乱码
问题描述:在PL/SQL客户端中执行insert语句,插入中文乱码 解决方案: 1.执行脚本 select userenv('language') from dual; 结果为AMERICAN_ ...
- ceshi
% void CLASS cam_xyz_coeff (float rgb_cam[3][4], double cam_xyz[4][3]) % { % double cam_rgb[4][3], i ...
- iOS多播放器封装
今年在做直播业务的时候遇到一些问题,就是在一个套播放器UI中需要多种不同的播放器(AVPlayer.IJKPlayer.AliPlayer)支持,根据ABTest开关来切换具体使用哪种播放器,并且还要 ...
- 基于.NET平台常用的框架整理
自从学习.NET以来,优雅的编程风格,极度简单的可扩展性,足够强大开发工具,极小的学习曲线,让我对这个平台产生了浓厚的兴趣,在工作和学习中也积累了一些开源的组件,就目前想到的先整理于此,如果再想到,就 ...
- 第一天ci框架开发商城1
ci框架开发商城1 1/28/2016 9:43:52 PM userguide删除 system application controllers 控制器 models 模型 views 视图 模板 ...
- DXUT源码阅读笔记
14.GetCapture() 函数功能:该函数取得捕获了鼠标的窗口(如果存在)的句柄.在同一时刻,只有一个窗口能捕获鼠标:此时,该窗口接收鼠标的输入,无论光标是否在其范围内.函数原型:HWND Ge ...
- Codeforces Round #377 (Div. 2)
#include <iostream> #include <stdio.h> #include <string.h> using namespace std; in ...
- Linux内核笔记--深入理解文件描述符
内核版本:linux-2.6.11 文件描述符(file descriptor)在Linux编程里随处可见,设备读写.网络通信.进程通信,fd可谓是关键中的关键. 深入理解可以增加我们使用它的信心. ...
- volatile不能保证原子性
1.看图自己体会 2.体会不了就给你个小程序 package cs.util; public class VolatileDemo { private volatile int count =0; p ...
- [翻译svg教程]svg学习系列 开篇
目录 [翻译svg教程]svg学习系列 开篇 [翻译svg教程 ]svg 的坐标系统 [翻译svg教程]svg 中的g元素 [翻译svg教程]svg中矩形元素 rect [翻译svg教程]svg中的c ...