设计模式与软考试题之职责链模式
2007年下半年软件设计师考试下午试题最后一题考查职责链模式(责任链模式),原题如下:
【全国计算机技术与软件专业技术资格(水平)考试 2007年下半年 软件设计师 下午试卷】
注:当年试题五、试题六和试题七三选一,试题六为C++版,试题七为Java版。
试题六
阅读以下说明和 C++代码,将应填入 (n) 处的字句写在答题纸的对应栏内。
【说明】
已知某企业的采购审批是分级进行的,即根据采购金额的不同由不同层次的主管人员来审批,主任可以审批5万元以下(不包括5万元)的采购单,副董事长可以审批5万元至10万元(不包括10万元)的采购单,董事长可以审批10万元至50万元(不包括50万元)的采购单,50万元及以上的采购单就需要开会讨论决定。
采用责任链设计模式(Chain of Responsibility)对上述过程进行设计后得到的类图如图6-1所示。
图6-1 设计类图(Sunny注:此图中成员变量的数据类型有点小问题)
[C++代码]
#include <string>
#include <iostream>
using namespace std;
class PurchaseRequest {
public:
double Amount; // 一个采购的金额
int Number; // 采购单编号
string Purpose; // 采购目的
};
class Approver { // 审批者类
public:
Approver(){ successor = NULL; }
virtual void ProcessRequest(PurchaseRequest aRequest){
if (successor != NULL){ successor-> (1) ; }
}
void SetSuccessor(Approver *aSuccesssor){ successor = aSuccesssor; }
private:
(2) successor;
};
class Congress : public Approver {
public:
void ProcessRequest(PurchaseRequest aRequest){
if(aRequest.Amount >= 500000){ /* 决定是否审批的代码省略 */ }
else (3) ProcessRequest(aRequest);
}
};
class Director : public Approver {
public:
void ProcessRequest(PurchaseRequest aRequest){ /* 此处代码省略 */ }
};
class President : public Approver {
public:
void ProcessRequest(PurchaseRequest aRequest){ /* 此处代码省略 */ }
};
class VicePresident : public Approver {
public:
void ProcessRequest(PurchaseRequest aRequest){ /* 此处代码省略 */ }
};
void main(){
Congress Meeting; VicePresident Sam; Director Larry ; President Tammy;
// 构造责任链
Meeting.SetSuccessor(NULL); Sam.SetSuccessor( (4) );
Tammy.SetSuccessor( (5) ); Larry.SetSuccessor( (6) );
PurchaseRequest aRequest; // 构造一采购审批请求
cin >> aRequest.Amount; // 输入采购请求的金额
(7) .ProcessRequest(aRequest); // 开始审批
return ;
}
试题七
阅读以下说明以及Java程序,将应填入 (n) 处的字句写在答题纸的对应栏内。
【说明】
已知某企业的采购审批是分级进行的,即根据采购金额的不同由不同层次的主管人员来审批,主任可以审批5万元以下(不包括5万元)的采购单,副董事长可以审批5万元至10万元(不包括10万元)的采购单,董事长可以审批10万元至50万元(不包括50万元)的采购单,50万元及以上的采购单就需要开会讨论决定。
采用责任链设计模式(Chain of Responsibility)对上述过程进行设计后得到的类图如图7-1所示。
图7-1 设计类图(Sunny注:此图中成员变量的数据类型有点小问题)
[Java代码]
class PurchaseRequest {
public double Amount; // 一个采购的金额
public int Number; // 采购单编号
public String Purpose; // 采购目的
}
class Approver { // 审批者类
public Approver(){ successor = null; }
public void ProcessRequest(PurchaseRequest aRequest){
if (successor != null){ successor. (1) ; }
}
public void SetSuccessor(Approver aSuccesssor){ successor = aSuccesssor; }
private (2) successor;
}
class Congress extends Approver {
public void ProcessRequest(PurchaseRequest aRequest){
if(aRequest.Amount >= 500000){ /* 决定是否审批的代码省略 */ }
else (3) .ProcessRequest(aRequest);
}
}
class Director extends Approver {
public void ProcessRequest(PurchaseRequest aRequest){ /* 此处代码省略 */ }
}
class President extends Approver {
public void ProcessRequest(PurchaseRequest aRequest){ /* 此处代码省略 */ }
}
class VicePresident extends Approver {
public void ProcessRequest(PurchaseRequest aRequest){ /* 此处代码省略 */ }
}
public class rs {
public static void main(String[] args) throws IOException {
Congress Meeting = new Congress();
VicePresident Sam = new VicePresident();
Director Larry = new Director();
President Tammy = new President();
// 构造责任链
Meeting.SetSuccessor(null); Sam.SetSuccessor( (4) );
Tammy.SetSuccessor( (5) ); Larry.SetSuccessor( (6) );
// 构造一采购审批请求
PurchaseRequest aRequest = new PurchaseRequest();
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
aRequest.Amount = Double.parseDouble(br.readLine());
(7) .ProcessRequest(aRequest); // 开始审批
return ;
}
}
------------------------------------------------------------------------------------------------------------------------------------------------------
分析与解答:
本题是职责链模式的一个典型应用实例,综合考查了职责链模式的多个实现要点,包括:
(1) 抽象处理者的引入;
(2) 请求的处理和传递;
(3) 客户端如何建链。
在职责链模式中,为了简化系统的设计,并且让系统能够很方便地增加新的请求处理者,引入了抽象处理者,在抽象处理者中维持了一个对当前处理者的下一个处理者(下家)的引用,而当前处理者的下家仍旧是抽象处理者的某个子类的对象,因此,抽象处理者(如本题中的Approver)将产生一个自关联。因此,第(2)空应该填Approver *(C++)或Approver(Java);当一个具体请求处理者无法处理某个请求时,需要将该请求传递给下家进行处理,因此在抽象处理者Approver的ProcessRequest()方法中需要判断一个处理者是否存在下家,如果存在的话,可以在需要时调用其下家的ProcessRequest()方法,因此第(1)空应该填ProcessRequest(aRequest)。在具体处理者类中,需要覆盖在抽象处理者中定义的ProcessRequest()方法,如果自己能够处理请求,则自己处理,否则,将调用在Approver中定义的ProcessRequest()方法来处理请求,此处,考查了C++和Java语言中如何在子类中调用父类的方法,如果是C++,可通过“父类名::方法名”的方式,如果是Java,则可以使用super关键字。
第(4)-(6)空比较简单,个人觉得这几空其实挺无聊的,,命题人故意把请求处理者对象的创建次序和建链次序搞乱,考查应试者是否知道如何在客户端建链。根据说明,采购审批次序为:主任(Larry) --> 副董事长(Sam) --> 董事长(Tammy) --> 开会(Meeting),因此,Larry的下家是Sam,Sam的下家为Tammy,Tammy的下家是Meeting,Meeting的下家为Null(没有下家)。当客户端递交采购单时,首先将采购单递交给审批权限最低的主任(Larry),如果Larry可以处理则自己处理,否则传递给下家(Sam)来处理;依此类推,直到有某一个处理者审批该采购单为止。因此,第(7)空应该填Larry,不过,Sunny个人觉得这一空并不严谨,事实上我们可以将该采购单(请求对象)递交给链上的任意一个处理者对象,只是可能会得不到处理而已,建议把最后一句注释改为“//从级别最低的主管人员开始审批”。
推荐:深入学习职责链模式
参考答案:
【试题六】
(1) ProcessRequest(aRequest)
(2) Approver *
(3) Approver::
(4) &Tammy
(5) &Meeting
(6) &Sam
(7) Larry
【试题七】
(1) ProcessRequest(aRequest)
(2) Approver
(3) super
(4) Tammy
(5) Meeting
(6) Sam
(7) Larry
【作者:刘伟 http://blog.csdn.net/lovelion】
设计模式与软考试题之职责链模式相关推荐
- C#设计模式学习笔记:(20)职责链模式
本笔记摘抄自:https://www.cnblogs.com/PatrickLiu/p/8109100.html,记录一下学习过程以备后续查用. 一.引言 今天我们要讲行为型设计模式的第八个模式--职 ...
- [转]23种经典设计模式的java实现_5_职责链模式
对于职责链模式,一般是这么定义的:使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系,即--将这些对象连成一条(处理)链,并沿着这条链传递该请求,直到这条链结束同时有一个对象处理它 ...
- 23种经典设计模式的java实现_5_职责链模式
对于职责链模式,一般是这么定义的:使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系,即--将这些对象连成一条(处理)链,并沿着这条链传递该请求,直到这条链结束同时有一个对象处理它 ...
- 设计模式系列之九:职责链模式
前言 责任链模式属于行为型设计模式,所谓责任链,就是把责任处理对象连成一条链,这样当一个处理对象不能及时处理的时候就会交给下一个处理对象处理,直到被处理为止.就像我们找人签字盖章的时候,当一个对象不能 ...
- 设计模式之职责链模式(Chain of Responsibility)摘录
23种GOF设计模式一般分为三大类:创建型模式.结构型模式.行为模式. 创建型模式抽象了实例化过程,它们帮助一个系统独立于如何创建.组合和表示它的那些对象.一个类创建型模式使用继承改变被实例化的类,而 ...
- Python设计模式-职责链模式
Python设计模式-职责链模式 代码基于3.5.2,代码如下; #coding:utf-8 #职责链模式class Handler():def __init__(self):self.success ...
- 设计模式之职责链模式、减小了因为分支带来的耦合
1. 定义 职责链模式(Chain of Responsibility):使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系.将这个对象连成一条链,并沿着这条链传递该请求,直到有一 ...
- C#设计模式之二十职责链模式(Chain of Responsibility Pattern)【行为型】
一.引言 今天我们开始讲"行为型"设计模式的第八个模式,该模式是[职责链模式],英文名称是:Chain of Responsibility Pattern.让我们看看现实生活中的例 ...
- Java设计模式(备忘录模式-解释器模式-状态模式-策略模式-职责链模式)
Java设计模式Ⅶ 1.备忘录模式 1.1 备忘录模式概述 1.2 代码理解 2.解释器模式 2.1 解释器模式概述 3.状态模式 3.1 状态模式概述 3.2 代码理解 4.策略模式 4.1 策略模 ...
最新文章
- 双指针问题最简单的教程(1)
- 以太坊经典逆势上涨,行情能否继续?
- java sleep线程吗_JAVA的线程的sleep()方法是否占用CPU
- Vue中使用Openlayers加载Geoserver发布的ImageWMS
- myelicesp stepover不能点_市区6处垃圾临时转运点被撤销
- element -ui 表单验证 如果 需要验证的v-model 是对象中的对象 总是提示没有填写....
- java编译后生成字节码_请问java源文件编译后怎么生成字节码文件?
- Mac Apache WebDav 服务器配置
- cg word List 3
- 2020年周记(2/50)
- vue 样式绑定 class
- ~~朴素版prim算法
- MySQL 数据库基础
- Smarty3——foreach
- 电脑模拟收银机_模拟超市的收银系统
- 牛课网--直通BAT面试算法精讲课--送优惠码啦
- SQLServer2008R2精简版使用
- Linux修改文件保存时报错E45: 已设定选项 ‘readonly‘ (请加 ! 强制执行)
- 武汉新时标文化传媒有限公司抖音小店公告标题怎么写?
- 处理软键盘的回车问题