37职责链模式(Chain of Responsibility Pattern)

动机(Motivate):
    在软件构建过程中,一个请求可能被多个对象处理,但是每个请求在运行时只能有一个接受者,如果显示指定,将必不可少地带来请求发送者与接受者的紧耦合。
    如何使请求的发送者不需要指定具体的接受者?让请求的接受者自己在运行时决定来处理请求,从而使两者解耦。
意图(Intent):
    使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。
结构图(Struct):
             

适用性:
    1.有多个对象可以处理一个请求,哪个对象处理该请求运行时刻自动确定。
    2.你想在不明确接收者的情况下,向多个对象中的一个提交一个请求。
    3.可处理一个请求的对象集合应被动态指定。
生活中的例子:
               

代码实现:
          

 1     //Handler
 2    abstract class Approver
 3     {
 4        protected Approver successor;
 5        public void SetSuccessor(Approver successor)
 6        {
 7            this.successor = successor;
 8        }
 9        public abstract void ProcessRequest(Purchase purchase);
10 
11     }
12 
13 
14 

 

 1     //ConcreteHandler
 2     class Director :Approver
 3     {
 4         public override void ProcessRequest(Purchase purchase)
 5         {
 6             if (purchase.Amount < 10000.0)
 7             {
 8                 Console.WriteLine("{0} approved request# {1}", this.GetType().Name, purchase.Number);
 9 
10             }
11             else if(successor !=null)
12             {
13                 successor.ProcessRequest(purchase);
14             }
15         }
16     }

 

 1 
 2 
 3 
 4     class VicePresident :Approver
 5     {
 6         public override void ProcessRequest(Purchase purchase)
 7         {
 8             if (purchase.Amount < 25000.0)
 9             {
10                 Console.WriteLine("{0} approved request# {1}", this.GetType().Name, purchase.Number);
11 
12             }
13             else if (successor != null)
14             {
15                 successor.ProcessRequest(purchase);
16             }
17         }
18     }

 

 1 
 2     class President :Approver
 3     {
 4         public override void ProcessRequest(Purchase purchase)
 5         {
 6             if (purchase.Amount < 100000.0)
 7             {
 8                 Console.WriteLine("{0} approved request# {1}", this.GetType().Name, purchase.Number);
 9 
10             }
11             else
12             {
13                 Console.WriteLine("Request! {0} requires an executive meeting!", purchase.Number);
14             }
15         }
16     }

 

 1 
 2 
 3     //Request details
 4     class Purchase
 5     {
 6         private int number;
 7         private double amount;
 8         private string purpose;
 9 
10         //Constructor
11         public Purchase(int number, double amount, string purpose)
12         {
13             this.number = number;
14             this.amount = amount;
15             this.purpose = purpose;
16         }
17         //Properties
18         public double Amount
19         {
20             get { return amount; }
21             set { amount = value; }
22         }
23         public string Purpose
24         {
25             get { return purpose; }
26             set { purpose = value; }
27         }
28         public int Number
29         {
30             get { return number; }
31             set { number = value; }
32         }
33     }


客户端调用如下:

 1 
 2     class Program
 3     {
 4         static void Main(string[] args)
 5         {
 6             //Setup Chain of Responsibility
 7             Director Larry = new Director();
 8             VicePresident Sam = new VicePresident();
 9             President Tammy = new President();
10             Larry.SetSuccessor(Sam);
11             Sam.SetSuccessor(Tammy);
12 
13             //Generate and process purchase requests
14             Purchase p = new Purchase(1034, 350.00, "Supplies");
15             Larry.ProcessRequest(p);
16 
17             p = new Purchase(2035, 32590.10, "Project X");
18             Larry.ProcessRequest(p);
19 
20             p = new Purchase(2036, 122100.00, "Project Y");
21             Larry.ProcessRequest(p);
22 
23             //Wait for user
24             Console.Read();
25         }
26     }



运行结果如下:
               

Chain of Responsibility实现要点:
    1.Chain of Responsibility模式的应用场合在于“一个请求可能有多个接受者,但是最后真正的接受者只胡一个”,只有这时候请求发送者与接受者的耦合才胡可能出现“变化脆弱”的症状,职责链的目的就是将二者解耦,从而更好地应对变化。
    2.应用了Chain of Responsibility模式后,对象的职责分派将更具灵活性。我们可以在运行时动态添加/修改请求的处理职责。
    3.如果请求传递到职责链的未尾仍得不到处理,应该有一个合理的缺省机制。这也是每一个接受对象的责任,而不是发出请求的对象的责任。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/438630.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

python3中format函数列表_Python3之字符串格式化format函数详解(上)

173.jpg概述在Python3中&#xff0c;字符串格式化操作通过format()方法或者fstring实现。而相比于老版的字符串格式化方式&#xff0c;format()方法拥有更多的功能&#xff0c;操作起来更加方便&#xff0c;可读性也更强。该函数将字符串当成一个模板&#xff0c;通过传入的参数…

38备忘录模式(Memento Pattern)

对象状态的回溯&#xff1a; 对象状态的变化无端&#xff0c;如何回溯/恢复对象在某个点的状态&#xff1f; 动机&#xff1a; 在软件构建过程中&#xff0c;某些对象的状态在转换过程中&#xff0c;可能由于某种需要&#xff0c;要求程序能够…

39策略模式(Strategy Pattern)

算法与对象的耦合&#xff1a; 对象可能经常需要使用多种不同的算法&#xff0c;但是如果变化频繁&#xff0c;会将类型变得脆弱... 动机&#xff1a; 在软件构建过程中&#xff0c;某些对象使用的算法可能多种多样&#xff0c;经常改变&#xff0c;如果将…

40访问者模式(Visitor Pattern)

类层次结构的变化&#xff1a; 类层次结构中可能经常由于引入新的操作&#xff0c;从而将类型变得脆弱... 动机&#xff1a; 在软件构建过程中&#xff0c;由于需求的改变&#xff0c;某些类层次结构中常常需要增加新的行为(方法),如果直接…

41状态模式(State Pattern)

对象状态影响对象行为&#xff1a; 对象拥有不同的状态&#xff0c;往往会行使不同的行为... 动机&#xff1a; 在软件构建过程中&#xff0c;某些对象的状态如果改变以及其行为也会随之而发生变化&#xff0c;比如文档处于只读状态&#xff0c;其支…

python中空格属于字符吗_举例说明python中空格是属于字符

python中空格属于字符吗&#xff1f;答案是肯定的&#xff0c;空格在Python中也是属于字符的。案例&#xff1a;输入一行字符&#xff0c;分别统计出其中英文字母、空格、数字和其它字符的个数。#!/usr/bin/python# -*- coding: UTF-8 -*-import strings raw_input(input a st…

【转】如何将域中的AD数据导入SharePoint

最近刚装好sharepoint2010&#xff0c;想要研究一下&#xff0c;第一件想做的事就是想把AD中的用户信息导入到SharePoint中。 那现在就来看看我是怎么操作的&#xff1a; 1.打开管理中心 sharepoint是通过“用户配置文件同步服务”来实现同步&#xff0c;所以第一步要开启这个…

Apsara Clouder专项技能认证:实现调用API接口

一.API 简介 1.API 的概念 API(Application Programming Interface应用程序编程接口)是一些预定义的函数,目的是提供应用程序与开发人员基于某软件或硬件得以访问一组例程的能力,而又无需访问源码或理解内部工作机制的细节 2.API 的特点 API 是一个明确定义的接口,可以为其…

第一节:复习委托,并且通过委托的异步调用开启一个新线程和异步回调、异步等待

一. 再谈委托 1. 委托是一个关键字为delegate的自定义类型&#xff0c;通过委托可以把方法以参数的形式传递给另外一个方法&#xff0c;实现插件式的开发模式&#xff1b; 同时调用委托的时候&#xff0c;委托所包含的所有方法都会被实现。 2. 委托的发展历史&#xff1a;new…

linux 修改 java 内存_Linux 和 Windows修改Java虚拟机内存大小

因为内存溢出问题1. Linux下直接修改%tomcat_home%/bin/catalina.sh文件在注释下紧接一行也就是脚本正文开始之前 加上Java_OPTS-server -Xms512m -Xmx1024m -XX:PermSize128m -XX:MaxPermSize512m如果报-x没有定义,则用declare -x JAVA_OPTS"-Xms512m -Xmx1024"初始…

第二节:深入剖析Thread的五大方法、数据槽、内存栅栏

一. Thread及其五大方法 Thread是.Net最早的多线程处理方式&#xff0c;它出现在.Net1.0时代&#xff0c;虽然现在已逐渐被微软所抛弃&#xff0c;微软强烈推荐使用Task(后面章节介绍)&#xff0c;但从多线程完整性的角度上来说&#xff0c;我们有必要了解下N年前多线程的是怎么…

java redis 生成唯一id_Redis在集群环境中生成唯一ID

概述设计目标&#xff1a;每秒最大生成10万个ID&#xff0c;ID单调递增且唯一。Reidis可以不需要持久化ID。要求:集群时钟不能倒退。总体思路&#xff1a;集群中每个节点预生成生成ID&#xff1b;然后与redis的已经存在的ID做比较。如果大于&#xff0c;则取节点生成的ID&#…

java await signal_【Java并发008】原理层面:ReentrantLock中 await()、signal()/signalAll()全解析...

一、前言上篇的文章中我们介绍了AQS源码中lock方法和unlock方法&#xff0c;这两个方法主要是用来解决并发中互斥的问题&#xff0c;这篇文章我们主要介绍AQS中用来解决线程同步问题的await方法、signal方法和signalAll方法&#xff0c;这几个方法主要对应的是synchronized中的…

第八节:Task的各类TaskTResult返回值以及通用线程的异常处理方案

一. Task的各种返回值-Task<TResult> PS&#xff1a; 在前面章节&#xff0c;我们介绍了Task类开启线程、线程等待、线程延续的方式&#xff0c;但我们并没有关注这些方式的返回值&#xff0c;其实他们都是有返回值的Task<TResult>&#xff0c;然后可以通过Task的…

mysql2005触发器修改成绩_创建、更改和删除触发器

创建、更改和删除触发器Creating, Altering, and Removing Triggers08/06/2017本文内容适用于&#xff1a;Applies to: SQL ServerSQL Server(所有支持的版本)SQL ServerSQL Server (all supported versions) Azure SQL 数据库Azure SQL DatabaseAzure SQL 数据库Azure SQL Dat…

第一节:从面向对象思想(oo)开发、接口、抽象类以及二者比较

一. 面向对象思想 1. 面向过程&#xff08;OP&#xff09;和面向对象&#xff08;OO&#xff09;的区别&#xff1a; (1)&#xff1a;面向过程就是排着用最简单的代码一步一步写下去&#xff0c;没有封装&#xff0c;当业务复杂的时候&#xff0c;改动就很麻烦了 (2)&#xff…

第二节:重写(new)、覆写(overwrite)、和重载(overload)

一. 重写 1. 关键字&#xff1a;new 2. 含义&#xff1a;子类继承父类中的普通方法&#xff0c;如果在子类中重写了一个和父类中完全相同的方法&#xff0c;子类中会报警告(问是否显式的隐藏父类的中的方法)&#xff0c;如果在子类中的方法前加上new关键字&#xff0c;则警告…

java 分页查询_JavaWeb之分页查询

时间&#xff1a;2016-12-11 01:411、分页的优点&#xff1a;只查询一页&#xff0c;不需要查询所有数据&#xff0c;能够提高效率。2、分页数据页面的数据都是由Servlet传递的* 当前页&#xff1a;pageCode> 如果页面没有向Servlet传递页码&#xff0c;那么Servlet默认…

第三节:深度剖析各类数据结构(Array、List、Queue、Stack)及线程安全问题和yeild关键字

一. 各类数据结构比较及其线程安全问题 1. Array(数组)&#xff1a; 分配在连续内存中,不能随意扩展&#xff0c;数组中数值类型必须是一致的。数组的声明有两种形式&#xff1a;直接定义长度&#xff0c;然后赋值&#xff1b;直接赋值。 缺点&#xff1a;插入数据慢。 优点&a…

第四节:IO、序列化和反序列化、加密解密技术

一. IO读写   这里主要包括文件的读、写、移动、复制、删除、文件夹的创建、文件夹的删除等常规操作。 注意&#xff1a;这里需要特别注意&#xff0c;对于普通的控制台程序和Web程序&#xff0c;将"相对路径"转换成"绝对路径"的方法不一致。 (1). 在w…