6

设计模式与软考试题之职责链模式

 3 years ago
source link: https://blog.csdn.net/LoveLion/article/details/8545122
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

设计模式与软考试题之职责链模式

       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


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK