职责链(Chain of Responsibility)职责链模式是一种行为模式,当多个对象都有机会处理请求的时候,为了避免请求的发送者和接收者之间的耦合关系,我们使用职责链模式将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。

职责链模式最常用的地方就是在UI组件响应点击事件的时候,今天我们就以此为例。

首先我们定义了一个基类:

public class Widget
{protected Widget _parent;public Widget(Widget parent){_parent = parent;}public virtual bool CanResponse(int x, int y){return false;}public virtual void HandleTouch(int x, int y){if (CanResponse(x, y)) {DoHandleTouch (x, y);} else {if (_parent != null) {_parent.HandleTouch (x, y);}}}protected virtual void DoHandleTouch(int x, int y){//TODOConsole.WriteLine("Touch on widget");}
}

在这个Widget基类里面,就定义了职责链的一些基本操作:连接后继者(parent),是否响应事件(CanResponse),传递事件(HandleTouch),处理事件(DoHandleTouch)。

我们可以实现继承自Widget的两个类:

public class Button : Widget
{protected int _x;protected int _y;protected int _w;protected int _h;public Button(Widget parent, int x, int y, int w, int h) : base(parent){_x = x;_y = y;_w = w;_h = h;}public override bool CanResponse(int x, int y){return ContainPoint (x, y);}protected bool ContainPoint(int x, int y){return x >= _x && x < _x + _w && y >= _y && y < _y + _h;}protected override void DoHandleTouch(int x, int y){//TODOConsole.WriteLine("Touch on button");}
}
public class Image : Widget
{public Image (Widget parent) : base(parent){}public override bool CanResponse(int x, int y){return !IsTransparentAtPoint (x, y);}protected bool IsTransparentAtPoint(int x, int y){//TODOreturn false;}protected override void DoHandleTouch(int x, int y){//TODOConsole.WriteLine("Touch on image");}
}

使用:

     Widget wdt = new Widget (null);Image img = new Image (wdt);Button btn = new Button (img, 0, 0, 100, 100);btn.HandleTouch (200, 300);

因为传入的x,y不在btn的区域里,所以将事件传递给了img,由img来处理事件。

职责链模式让我想起了RPG游戏里面两个很有趣的技能,护卫和伤害转移,简单实现以下:

public abstract class Battler
{public string Name { get; protected set;}public Battler(string name){Name = name;}protected Battler _damageTaker;public void TransferDamageTo(Battler taker){_damageTaker = taker;}public int HP { get; set;}public void BeDamaged(int dmg){if (_damageTaker != null) {_damageTaker.BeDamaged (dmg);} else {HP -= dmg;Console.WriteLine (Name + " is damaged");}}public int Attack{ get; set; }public void AttackTo(Battler battler){Console.WriteLine (Name + "is attacking");battler.BeDamaged (Attack);}
}public class Hero : Battler
{public Hero(string name) : base(name){HP = 100;Attack = 20;}public void Protect(Hero other){other.TransferDamageTo (this);}
}public class Monster : Battler
{public Monster(string name) : base(name){HP = 200;Attack = 10;}
}

使用:

     Hero snow = new Hero ("snow");Hero pino = new Hero ("pino");Monster monster = new Monster ("monster");Monster frog = new Monster ("forg");pino.Protect (snow);pino.TransferDamageTo (monster);frog.AttackTo (snow);

pino护卫了snow,又将伤害转移给frog,所以当monster攻击的时候,frog承受了伤害。

这段代码算是职责链模式的变种,因为职责链模式只有本对象无法处理事件的时候才会传递给后继者,而这段代码是只有没有后继者的时候才会处理事件。

职责链模式的优点在于降低了耦合度,事件的发送者和接收者都没有对方明确的信息,而且我们可以实现多种多样的职责链结构(例如树形),而链中的对象不需要知道它所处的是怎样的结构。并且职责链模式增强了分派事件的灵活性,可以动态的修改链的结构,增加、删除或者调整顺序。

缺点在于,不能保证事件可以被处理,因为并不一定有对象可以相应事件。而且这样也增加了系统的复杂性,会增加排错的难度。

小话设计模式(十三)职责链模式相关推荐

  1. 设计模式之职责链模式应用例题

    设计模式之职责链模式应用例题 题目描述 类结构图及相关说明 程序代码 运行结果 题目描述 在军队中,一般根据战争规模的大小和重要性由不同级别的长官(Officer)来下达作战命令,情报人员向上级递交军 ...

  2. 【设计模式】—— 职责链模式ChainOfResponsibility

    模式意图 避免请求的发送者,和接受者过度的耦合在一起.一个请求者只需要发送一个请求即可,它的请求具体由后面哪个对象进行响应,并不需要关心.而请求的接受者可以自己处理它,也可以把它像链条一样向后传. 因 ...

  3. python设计模式案例分析_Python设计模式之职责链模式原理与用法实例分析

    本文实例讲述了Python设计模式之职责链模式原理与用法.分享给大家供大家参考,具体如下: 职责链模式(Chain Of Responsibility):使多个对象都有机会处理请求,从而避免发送者和接 ...

  4. 【设计模式】职责链模式(C#)

    [设计模式]职责链模式 1.概述 在现实生活中,常常会出现这样的事例:一个请求有多个对象可以处理,但每个对象的处理条件或权限不同.例如,公司员工请假或者加薪,可处理的领导有HR.部门负责人.副总经理. ...

  5. 设计模式之职责链模式、减小了因为分支带来的耦合

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

  6. 『设计模式』职责链模式(Chain of Responsibility) 可怜的加薪、请假之路

    23种设计模式+额外常用设计模式汇总 (持续更新) 问题抽象 客户端发出一个请求,会有很多对象都可以来处理这个请求,而且不同对象的处理逻辑是不一样的. 对于客户端而言,无所谓谁来处理,反正有对象处理就 ...

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

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

  8. 设计模式复习-职责链模式

    #pragma once #include "stdafx.h" #include<set> #include<string> #include<io ...

  9. JBPM与设计模式之职责链模式

    上篇我们了解并学习了JBPM的长事务实现,其中用到了设计模式中的职责链模式和命令模式:这块还是很有厚重感的,我们可以从中学到很多的东西:今天我们先来学习一下职责链模式. 职责链模式定义 使多个对象都有 ...

  10. C++设计模式14——职责链模式

    https://blog.csdn.net/CoderAldrich/article/details/83183388 什么是职责链模式? 在GOF的<设计模式:可复用面向对象软件的基础> ...

最新文章

  1. Linux中文件系统简介
  2. mysql jdbc 表结构_JavaEE_day09_MySQL多表JDBC
  3. k8s强制删除pod
  4. sum() over()函数使用
  5. HEU 1031 Basic Remains
  6. oracle清理trace、alert、aud、listener等日志文件
  7. Rhino(js的java实现组件)
  8. oracle 查询数据库表空间大小和剩余空间
  9. tomcat监听activemq jms配置
  10. matlb:图像的几何矩,中心矩,Hu不变矩(含代码)
  11. SpreadJS 15.1 ~【SpreadJS 15.0】
  12. 信号-失真噪声比 (SNDR) 无杂散动态范围 (SFDR)
  13. C++新特性28_线程同步问题的产生原因(高级语言转为低级语言执行,时间片交替运行多线程中代码,代码切换过程中出现的问题)
  14. 我说Java完全面向对象,老大过来就是一jio
  15. Pytorch实现性别识别,男女分类
  16. 手机变窃听器 !CIA正在盯着你
  17. win10系统steam连接不上服务器,win10系统steam无法连接到更新服务器的解决方法
  18. EventBus使用与分析
  19. AI遮天传 DL-CNN
  20. RK3399 Android7.1修改安兔兔等第三方软件读到的内核版本信息

热门文章

  1. 使用Unison同步服务器目录
  2. http://coffeejp.com/bbs/forum.php?mod=viewthread,问题列表_华泰证券网络路演_新浪网
  3. BZOJ3420[POI2013]Triumphal archBZOJ5174[Jsoi2013]哈利波特与死亡圣器——树形DP+二分答案...
  4. LeetCode-729. 我的日程安排表 I
  5. 博弈论读书笔记(二):纳什均衡与野猪博弈
  6. [Hadoop培训笔记]07-HDFS详细分析三
  7. 标识符——C语言基础知识
  8. vue3 + vite中按需使用ace-builds实现编辑器
  9. 计算机科学班会,计算机科学与技术学院20级13班召开“砥砺前行,“计”往开来”主题班会...
  10. 【转帖】用友和金蝶应避免重蹈Oracle覆辙