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

       2007年下半年软件设计师考试下午试题最后一题考查职责链模式(责任链模式),原题如下:

 

【全国计算机技术与软件专业技术资格(水平)考试 2007年下半年 软件设计师 下午试卷】


注:当年试题五、试题六和试题七三选一,试题六为C++版,试题七为Java版。

 

试题六

       阅读以下说明和 C++代码,将应填入 (n) 处的字句写在答题纸的对应栏内。

【说明】

       已知某企业的采购审批是分级进行的,即根据采购金额的不同由不同层次的主管人员来审批,主任可以审批5万元以下(不包括5万元)的采购单,副董事长可以审批5万元至10万元(不包括10万元)的采购单,董事长可以审批10万元至50万元(不包括50万元)的采购单,50万元及以上的采购单就需要开会讨论决定。

       采用责任链设计模式(Chain of Responsibility)对上述过程进行设计后得到的类图如图6-1所示。

设计模式与软考试题之职责链模式_第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所示。

设计模式与软考试题之职责链模式_第2张图片

图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

你可能感兴趣的:(设计模式,软考)