0
点赞
收藏
分享

微信扫一扫

软件体系结构与设计模式之职责链模式和命令模式

一. 单选题(共5题)

  1. (单选题)下图描述了一种设计模式,该设计模式不可以( )。 image.png A. 动态决定由一组对象中某个对象处理该请求 B. 动态指定处理一个请求的对象集合,并高效率地处理一个请求 C. 使多个对象都有机会处理请求,避免请求的发送者和接收者间的耦合关系 D. 将对象连成一条链,并沿着该链传递请求 我的答案: B:动态指定处理一个请求的对象集合,并高效率地处理一个请求;正确答案: B:动态指定处理一个请求的对象集合,并高效率地处理一个请求;

  2. (单选题)接力赛跑体现了( )设计模式。 A. 职责链 (Chain of Responsibility) B. 命令 (Command) C. 备忘录 (Memento) D. 工厂方法 (Factory Method) 我的答案: A:职责链 (Chain of Responsibility) ;正确答案: A:职责链 (Chain of Responsibility) ;

  3. (单选题)以下关于命令模式的叙述错误的是( )。 A. 命令模式将一个请求封装为一个对象,从而使我们可用不同的请求对客户进行参数化 B. 命令模式可以将请求发送者和请求接收者解耦 C. 使用命令模式会导致某些系统有过多的具体命令类,导致在有些系统中命令模式变得不切实际 D. 命令模式是对命令的封装,命令模式把发出命令的责任和执行命令的责任集中在同一个类中,委派给统一的类来进行处理 我的答案: D:命令模式是对命令的封装,命令模式把发出命令的责任和执行命令的责任集中在同一个类中,委派给统一的类来进行处理;正确答案: D:命令模式是对命令的封装,命令模式把发出命令的责任和执行命令的责任集中在同一个类中,委派给统一的类来进行处理;

  4. (单选题)在( )时无须使用命令模式。 A. 实现撤销(Undo)操作和恢复(Redo)操作 B. 将请求的发送者和接收者解耦 C. 不改变聚合类的前提下定义作用于聚合中元素的新操作 D. 不同的时间指定请求,并将请求排队 我的答案: C:不改变聚合类的前提下定义作用于聚合中元素的新操作;正确答案: C:不改变聚合类的前提下定义作用于聚合中元素的新操作;

  5. (单选题)以下应用场景错误的是( )。 A. Java中的错误捕获机制运用了职责链模式 B. Javascript事件处理模型是一种不纯的职责链模式 C. 学校OA系统的公文审批是职责链模式的应用实例 D. 你委托快递小哥给家人送礼物使用了中介模式 我的答案: D:你委托快递小哥给家人送礼物使用了中介模式;正确答案: D:你委托快递小哥给家人送礼物使用了中介模式;

二. 填空题(共2题) 6. (填空题)已知某企业的采购审批是分级进行的,即根据采购金额的不同由不同层次的主管人员来审批,主任可以审批5 万元以下(不包括5 万元)的采购单,副董事长可以审批5 万元至10万元(不包括10 万元)的采购单,董事长可以审批10 万元至50 万元(不包括50万元)的采购单,50 万元及以上的采购单就需要开会讨论决定。 采用职责链设计模式对上述过程进行设计后得到的类图如图1所示。 image.png

【Java代码】

class PurchaseRequest {

 public double amount;  //一个采购的金额

 public int number;  //采购单编号

 public String purpose;  //采购目的

}



class Approver {  //审批者类

    private      (1)      successor;

    public Approver() { successor = null; }

    public void processRequest(PurchaseRequest aRequest){

     if(successor!=null) {successor.         (2)          ;}

    }

    public void setSuccessor(Approver aSuccessor) { successor = aSuccessor;}

    

}



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 Test

{

 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);

 }

}

正确答案: (1) Approver (2) processRequest(aRequest) (3) super (4) tammy (5) meeting (6) sam (7) larry 7. (填空题)已知某企业欲开发一家用电器遥控系统,即用户使用一个遥控器即可控制某些家用电器的开与关。遥控器如图1所示。该遥控器共有4个按钮,编号分别是0至3,按钮0和2能够遥控打开电器1和电器2,按钮1和3则能遥 控关闭电器1和电器2。由于遥控系统需要支持形式多样的电器,因此,该系统的设计要求具有较高的扩展性。现假设需要控制客厅电视和卧室电灯,对该遥控系统进行设计所得类图如图2所示。 image.png image.png 图2中,类RemoteController的方法onPressButton(int button)表示当遥控器按钮按下时调用的方法,参数为按键的编号;Command接口中on和off方法分别用于控制电器的开与关;Light中turnLight(int degree)方法用于调整电灯灯光的强弱,参数degree值为0时表示关灯,值为100时表示开灯并且将灯光亮度调整到最大;TV中setChannel(int channel)方法表示设置电视播放的频道,参数channel值为0时表示关闭电视,为1时表示开机并将频道切换为第1频道。

【Java代码】

class Light{ //电灯类

    public void turnLight(int degree) {//调整灯光亮度,0表示关灯,100表示亮度最大}

}



class TV{ //电视机类

    public void setChannel(int channel) {//0表示关机,1表示开机并切换到1频道}

}



interface Command{ //抽象命令类

    void on();

    void off();

}



class RemoteController{ //遥控器类

    //遥控器有4个按钮,按照编号分别对应4个Command对象

    protected Command[] commands = new Command[4]; 

    //按钮被按下时执行命令对象中的命令

    public void onPressButton(int button) {

        if(button%2==0) commands[button].on();

        else commands[button].off();

    }



    public void setCommand(int button, Command command){

      (1)    = command; //设置每个按钮对应的命令对象

    }

}



class LightCommand implements Command{  //电灯命令类

    protected Light light; //指向要控制的电灯对象

    public void on() {light.turnLight(100);}

    public void off() {light.  (2)   ;}

    public LightCommand(Light light) {this.light = light; }

}



class TVCommand implements Command{ //电视机命令类

    protected TV tv;

    public void on() {tv.  (3)   ;}

    public void off() {tv.setChannel(0);}

    public TVCommand(TV tv) {this.tv = tv;}

}



public class Test

{

    public static void main(String args[])

    {

        //创建电灯和电视对象

        Light light = new Light();

        TV tv = new TV();

        LightCommand lightCommand = new LightCommand(light);

        TVCommand tvCommand = new TVCommand(tv);

        RemoteController remoteController = new RemoteController();

        //设置按钮和命令对象

        remoteController.setCommand(0,  (4)   );  //此处设置电视命令

        ...//此处省略设置按钮1、按钮2和按钮3的命令对象代码

    }

本题中,应用命令模式能够有效地让类 (5) 和类 Light和TV 之间的耦合性降至最小。类 (6) 是请求发送者。具体命令类有 (7) 个,类Light和TV 是请求 (8)。

正确答案: (1) commands[button] (2) turnLight(0) (3) setChannel(1) (4) tvCommand (5) RemoteController (6) RemoteController (7) 2 (8) 接收者

三. 简答题(共2题) 8. (简答题)假设某公司的订单业务处理流程如下: 当有一笔订单进来,会先在后台通过初审人员进行审批,初审不通过,订单流程结束。初审通过以后,会转给终审人员进行审批,不通过,流程结束;通过,流转到财务人员进行处理。请用职责链模式模拟该场景。

1、画出UML图描述出相应的角色。 image.png 2、给出Java程序代码,程序代码有恰当的注释。

public class Test {
   public static void main(String[] args) {
       Approver preliminaryAuditor = new PreliminaryAuditor();
       Approver finalAdjudicator = new FinalAdjudicator();
       Approver financialStaff = new FinancialStaff();
       preliminaryAuditor.setSuccessor(finalAdjudicator);
       finalAdjudicator.setSuccessor(financialStaff);
       OrderRequest request=new OrderRequest();
       request.amount=10000;
       request.number=1000;
       preliminaryAuditor.processRequest(request);
   }
}

====================================================

class Approver {  //审批者类
   private Approver successor;
   public Approver() {
       successor = null;
   }
   public void processRequest(OrderRequest request) {
       if (successor != null) {
           successor.processRequest(request);
       }
   }
   public void setSuccessor(Approver aSuccessor) {
       successor = aSuccessor;
   }
}

public class OrderRequest {
   public double amount;  //一个采购的金额
   public int number;  //采购单编号
}

//初审人员

public class PreliminaryAuditor extends Approver{
   public void processRequest(OrderRequest request) {
       if (request.number>=10){
           System.out.println("初审,审核数量通过!!!");
           if (request.amount <= 1000) {
               System.out.println("初审人员,审计"+request.amount+"元,审核通过");
           } else {
               super.processRequest(request);
           }
       }else {
           System.out.println("初审,审核数量未通过,订单流程结束!!!");
       }
   }
}

//终审人员

public class FinalAdjudicator extends Approver{
   public void processRequest(OrderRequest request) {
       if (request.number>=100) {
           System.out.println("终审,审核数量通过!!!");
           if (request.amount <= 5000) {
               System.out.println("终审人员,审计" + request.amount + "元,审核通过");
           } else {
               super.processRequest(request);
           }
       }else {
           System.out.println("终审,审核数量未通过,订单流程结束!!!");
       }
   }
}

//财务人员

public class FinancialStaff extends Approver {
   public void processRequest(OrderRequest request) {
       if (request.amount <= 10000) {
           System.out.println("财务人员,审计" + request.amount + "元,审核通过");
       } else {
           System.out.println("数额太大没有权限!审核失败");
       }
   }
}

3、代码效果图 image.png

  1. (简答题)为了用户使用方便,某系统提供了一系列功能键,用户可以自定义功能键的功能,如功能键FunctionButton可以用于退出系统(SystemExitClass),也可以用于打开帮助界面(DisplayHelpClass)。用户可以通过修改配置文件来改变功能键的用途,现使用命令模式来设计该系统,使得功能键类与功能类之间解耦,相同的功能键可以对应不同的功能。 1、画出UML图描述相应的角色。 image.png 2、给出Java程序代码,程序代码有恰当的注释。
<?xml version="1.0" encoding="UTF-8" ?>
<config>
  <className>four.ExitCommand</className>
</config>

===================================

import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import java.io.File;

public class XMLUtil
{
  public static Object getBean()
  {
     try
     {
        DocumentBuilderFactory dFactory = DocumentBuilderFactory.newInstance();
        DocumentBuilder builder = dFactory.newDocumentBuilder();
        Document doc;                    
        doc = builder.parse(new File("homework-11/FactoryMethodconfig.xml"));
        NodeList nl = doc.getElementsByTagName("className");
           Node classNode=nl.item(0).getFirstChild();
           String cName=classNode.getNodeValue();
           Class c=Class.forName(cName);
         Object obj=c.newInstance();
           return obj;
          }  
              catch(Exception e)
              {
                 e.printStackTrace();
                 return null;
              }
     }
}

========================================

public class Client {
   public static void main(String[] args) {
       FunctionButton functionButton = new FunctionButton();
       Object bean = XMLUtil.getBean();
       functionButton.setCommand(bean);
       functionButton.click();
   }
}

=======================================

public class DisplayHelpClass {
   public void help(){
       System.out.println("打开帮助界面");
   }
}

public class FunctionButton {
   private Command command;

   public void setCommand(Object command) {
       this.command = (Command) command;
   }

   public void click(){
       command.execute();
   }
}

public class SystemExitClass {
   public void exit(){
       System.out.println("退出系统");
   }
}

=======================================

public interface Command {
   public void execute();
}
public class ExitCommand implements Command {
   private SystemExitClass exitClass;

   public ExitCommand() {
       exitClass=new SystemExitClass();
   }

   @Override
   public void execute() {
       exitClass.exit();
   }
}

public class HelpCommand implements Command {
   private DisplayHelpClass displayHelpClass;

   public HelpCommand() {
       displayHelpClass=new DisplayHelpClass();
   }

   @Override
   public void execute() {
       displayHelpClass.help();
   }
}

3、代码效果图 image.png

举报

相关推荐

0 条评论