201111软设下午真题

第 1 题

【说明】
某公司欲开发招聘系统以提高招聘效率,其主要功能如下:
(1)接受申请
验证应聘者所提供的自身信息是否完整,是否说明了应聘职位,受理验证合格的申请,给应聘者发送致谢信息。
(2)评估应聘者
根据部门经理设置的职位要求,审查已经受理的申请;对未被录用的应聘者进行谢绝处理,将未被录用的应聘者信息存入未录用的应聘者表,并给其发送谢绝决策;对录用的应聘者进行职位安排评价,将评价结果存入评价结果表,并给其发送录用决策,发送录用职位和录用者信息给工资系统。
现采用结构化方法对招聘系统进行分析与设计,获得如图1-1所示的顶层数据流图、图1-2所示0层数据流图和图1-3所示1层数据流图。

                                                                                图1-2 0层数据流图

                                                                          图1-3 1层数据流图

【问题1】(3分)
使用说明中的术语,给出图中E1~E3所对应的实体名称。
【问题2】(2分)
使用说明中的术语,给出图中D1~D2所对应的数据存储名称。
【问题3】(6分)
使用说明和图中的术语,给出图1-3中加工P1~P3的名称。
【问题4】(4分)
解释说明图1-2和图1-3是否保持平衡,若不平衡请按如下格式补充图1-3中数据流的名称以及数据流的起点或终点,使其平衡(使用说明中的术语或图中符号)。


**答案与解析** - 试题难度:较难 - 知识点:数据流图>数据流图 - 试题答案:
【问题1】(3分,各1分)
E1:应聘者E2:部门经理E3:工资系统
【问题2】(2分,各1分)
D1:未录用的应聘者表    D2:评价结果表
【问题3】(6分,各2分)
P1:验证信息P2:审查申请P3:职位安排评价
【问题4】(4分)
不平衡。图1-2中加工的输入输出流与其子图1-3中的输入输出流的数量不同。



- 试题解析:

    本题考查数据流图(DFD)的应用,是一种比较传统的题目,要求考生细心分析题目中所描述的内容。DFD是一种便于用户理解、分析系统数据流程的图形工具。是系统逻辑模型的重要组成部分。
【问题1】   
本问题要求我们给出图1-1中的实体E1~E3的名称。这个需要我们从题目中的描述和该图来获得。题目中有信息描述:“验证应聘者所提供的自身信息是否完整,是否说明了应聘职位,受理验证合格的申请,给应聘者发送致谢信息”我们结合0层数据流图可知,E1为应聘者;另外,根据题目描述“根据部门经理设置的职位要求,审查已经受理的申请”,再结合顶层图,我们可以知道E2是部门经理,再根据描述“发送录用职位和录用者信息给工资系统”和顶层数据流图可知,E3是工资系统。
【问题2】
本问题考查数据存储的确定。根据题目的描述“对未被录用的应聘者进行谢绝处理,将未被录用的应聘者信息存入未录用的应聘者表”,结合1层数据流图我们可知D1为未录用的应聘者表;根据题目描述“对录用的应聘者进行职位安排评价,将评价结果存入评价结果表”,再结合1层数据流图我们可知D2为评价结果表。
【问题3】
本题要求我们找出图中缺失的加工名称。对比图1-2和1-3我们不难发现,图1-3中的上半部分为图1-2中加工“接受申请”转换而来,而下半部分是图1-2中加工“评估应聘者”转换而来,那么根据题目描述“验证应聘者所提供的自身信息是否完整,是否说明了应聘职位,然后受理验证合格的申请”,我们可以知道这里应该有两个加工,分别是“验证信息”和“受理申请”,因此P1应该为“验证信息”。而根据题目描述“审查已经受理的申请;对未被录用的应聘者进行谢绝处理,将未被录用的应聘者信息存入未录用的应聘者表,并给其发送谢绝决策;对录用的应聘者进行职位安排评价”,我们可以知道,这里应该牵涉到三个加工,分别是“审查申请”、“谢绝应聘者”和“职位安排评价”,再结合图1-3,我们不难知道P2应该为“审查申请”,P3为“职位安排评价”。
【问题4】
    本题主要考查父图与子图的平衡原则。在0层数据流图中,加工“接受申请”输入数据流有“应聘者信息”、“应聘职位”,而其输出数据流有“致谢信息”和“已受理的申请”,而在1层数据流图的上半部分中,体现出来“应聘者信息”、“应聘职位”和“致谢信息”这些数据流,而没有“已受理的申请”这条输出数据流,因此这里缺少了这条数据流,其起点是加工“受理申请”。
    而同样的道理,我们可以知道在0层数据流图中与加工“评估应聘者”有关的数据流在1层数据流图中缺失了“录用职位”这条数据流,而这条数据流的起点是“P3”,其终点应该是E3;另外从与“评估应聘者”到E1有一条“决策”数据流,而在1层数据流图中体现出来的是“录用决策”,但根据题目意思,决策应该有录用决策和谢绝决策之分,应该还缺失了“谢绝决策”这条数据流,其起点是加工“谢绝应聘者”,其终点是“E1”。

第 2 题

【说明】
某物流公司为了整合上游供应商与下游客户,缩短物流过程,降低产品库存,需要构建一个信息系统以方便管理其业务运作活动。
【需求分析结果】
(1)物流公司包含若干部门,部门信息包括部门号、部门名称、经理、电话和邮箱。一个部门可以有多名员工处理部门的日常事务,每名员工只能在一个部门工作。每个部门有一名经理,只需负责管理本部门的事务和人员。
(2)员工信息包括员工号、姓名、职位、电话号码和工资;其中,职位包括:经理、业务员等。业务员根据托运申请负责安排承运货物事宜,例如:装货时间、到达时间等。一个业务员可以安排多个托运申请,但一个托运申请只由一个业务员处理。
(3)客户信息包括客户号、单位名称、通信地址、所属省份、联系人、联系电话、银行账号,其中,客户号唯一标识客户信息的每一个元组。每当客户要进行货物托运时,先要提出货物托运申请。托运申请信息包括申请号、客户号、货物名称、数量、运费、出发地、目的地。其中,一个申请号对应唯一的一个托运申请;一个客户可以有多个货物托运申请,但一个托运申请对应唯一的一个客户号。
【概念模型设计】
根据需求阶段收集的信息,设计的实体联系图和关系模式(不完整)如图2-1所示。

 
【关系模式设计】
部门(部门号,部门名称,经理,电话,邮箱)
员工(员工号,姓名,职位,电话号码,工资,   (a)   )
客户(   (b)   ,单位名称,通信地址,所属省份,联系人,联系电话,银行账号)
托运申请(   (c)  ,货物名称,数量,运费,出发地,目的地)
安排承运(   (d)  ,装货时间,到达时间,业务员)
 

【问题1】(5分)
根据问题描述,补充四个联系、联系的类型,以及实体与子实体的联系,完善图2-1所示的实体联系图。
【问题2】(8分)
根据实体联系图,将关系模式中的空(a)~(d)补充完整。分别指出部门、员工和安排承运关系模式的主键和外键。
【问题3】(2分)
若系统新增需求描述如下:
为了数据库信息的安全性,公司要求对数据库操作设置权限管理功能,当员工登录系统时,系统需要检查员工的权限。权限的设置人是部门经理。为满足上述需要,应如何修改(或补充)图2-1所示的实体联系图,请给出修改后的实体联系图和关系模式。

答案与解析

  • 试题难度:较难
  • 知识点:数据库设计>数据库设计
  • 试题答案:

    【问题1】(5分)


    【问题2】(8分)</p>

 

【问题3】(2分,联系1分,关系模式1分)

关系模式:权限(员工号,权限,设置人)或权限(<u>员工号</u>,权限,部门经理)。</p>
  • 试题解析:

    试题分析
        本题考查数据库概念结构设计、概念至逻辑结构转换等内容。
        此类题目要求考生认真阅读题目,根据题目的需求描述,给出实体间的联系。
    【问题1
    本题主要考查根据题目描述补充完整ER图。
        在本题中,根据题目描述“一个部门可以有多名员工处理部门的日常事务,每名员工只能在一个部门工作”,我们可以知道部门与员工间存在一对多的联系“属于”;根据题目描述“每个部门有一名经理,只需负责管理本部门的事务和人员”我们可以知道,经理与部门之间存在一对一的管理联系;然后我们根据题目描述“业务员根据托运申请负责安排承运货物事宜,一个业务员可以安排多个托运申请,但一个托运申请只由一个业务员处理”可知,在业务员和托管申请之间存在一个1对多的安排承运的联系;而根据题目描述“每当客户要进行货物托运时,先要提出货物托运申请。其中,一个申请号对应唯一的一个托运申请;一个客户可以有多个货物托运申请,但一个托运申请对应唯一的一个客户号”可以,客户和托运申请之间存在一个1对多的申请联系。另外,不管是业务员还是经理,他们都是员工,因此业务员和经理是员工实体的子实体。
    【问题2
        该问题要我们补充完整各关系模式中缺失的属性并给出各关系模式的主键。要补充各关系模式缺失的属性应该根据题目的描述和ER图转换为关系模式的转换原则来完成。a空是要我们补充员工信息关系模式所缺失的属性,根据题目的描述,员工信息包括:员工号、姓名、职位、电话号码和工资,而这些已经存在于员工关系模式中了,但是根据ER转换的原则,我们知道部门与员工之间存在一对多的联系,而这个联系没有转换为独立的关系模式,因此,需要将联系的属性和1端关系模式的主键放到多端当中来作为外键,因此a空应填属性“部门号”。其中员工关系模式的主键为员工号,而外键为部门号。
        b空是要我们补充客户关系模式所缺失的属性,根据题目的描述,客户信息包括客户号、单位名称、通信地址、所属省份、联系人、联系电话、银行账号。因此b空应该填“客户号”这个属性。
        c空是要我们补充托运申请关系模式所缺失的属性。根据题目描述托运申请信息包括申请号、客户号、货物名称、数量、运费、出发地、目的地。再结合ER图分析可得出c空应该填“申请号,客户号”。
        d空是要我们补充安排承运关系模式所缺失的属性。安排承运是有联系转换而来的一个关系模式,其中包含的属性应该包括其本身的属性和联系两端实体关系模式的主键,应该可知d空应该填“申请号”,而业务员的主键就是属性“业务员”。这个关系模式的主键应该是申请号,而外键是业务员,因为业务员是业务员关系模式的主键,其实就是员工号。
        同样的道理,对于部门关系模式,其主键为部门号,而外键为“经理”。
    【问题3
        根据本题描述“为了数据库信息的安全性,公司要求对数据库操作设置权限管理功能,当员工登录系统时,系统需要检查员工的权限。权限的设置人是部门经理。”我们就可以知道,应该有一个实体“权限”,而这个实体与部门经理之间存在一种一对多的联系,其中部门经理端为一端。

第 3 题

【说明】
Pay&Drive系统(开多少付多少)能够根据驾驶里程自动计算应付的费用。
系统中存储了特定区域的道路交通网的信息。道路交通网由若干个路段(Road Segment)构成,每个路段由两个地理坐标点(Node)标定,其里程数(Distance)是已知的。在某些地理坐标点上安装了访问控制(Access Control)设备,可以自动扫描行驶卡(Card)。行程(Trajectory)由一组连续的路段构成。行程的起点(Entry)和终点(Exit)都装有访问控制设备。
系统提供了3种行驶卡。常规卡(Regular Card)有效期(Valid Period)为一年,可以在整个道路交通网内使用。季卡(Season Card)有效期为三个月,可以在整个道路交通网内使用。单次卡(Minitrip Card)在指定的行程内使用,且只能使用一次。其中,季卡和单次卡都是预付卡(Prepaid Card),需要客户(Customer)预存一定的费用。
系统的主要功能有:客户注册、申请行驶卡、使用行驶卡行驶等。
使用常规卡行驶,在进入行程起点时,系统记录行程起点、进入时间(Date Of Entry)等信息。在到达行程终点时,系统根据行驶的里程数和所持卡的里程单价(Unit Price)计算应付费用,并打印费用单(Invoice)。
季卡的使用流程与常规卡类似,但是不需要打印费用单,系统自动从卡中扣除应付费用。
单次卡的使用流程与季卡类似,但还需要在行程的起点和终点上检查行驶路线是否符合该卡所规定的行驶路线。
现采用面向对象方法开发该系统,使用UML进行建模。构建出的用例图和类图分别如图3-1和图3-2所示。

【问题1】(4分)
根据说明中的描述,给出图3-1中U1和U2所对应的用例,以及(1)所对应的关系。
【问题2】(8分)
根据说明中的描述,给出图3-2中缺少的C1~C6所对应的类名以及(2)~(3)处所对应的多重度(类名使用说明中给出的英文词汇)。
【问题3】(3分)
根据说明中的描述,给出Road Segment、Trajectory和Card所对应的类的关键属性(属性名使用说明中给出的英文词汇)。

答案与解析

  • 试题难度:较难
  • 知识点:UML建模>用例图
  • 试题答案:

    【问题1】(4分)
    U1:使用常规卡行驶  U2:使用单次卡行驶 (各1分)
    (1):extend    (2分)
    【问题2】(8分,各1分)
    C1:RoadSegment    C2:Trajectory   C3:Card
    C4:RegularCard     C5:PrepaidCard  C6:MinitripCard
    (2)1          (3)1..3
    【问题3】(3分,每个类1分)
    RoadSegment的属性:Distance
    Trajectory的属性:Entry、Exit、DateOfEntry
    Card的属性:UnitPrice、ValidPeriod
     

  • 试题解析:

    试题分析
        本题考查面向对象开发相关知识,涉及UML用例图、类图以及类图设计时的设计模式。UML目前在面向对象软件开发中广泛使用,是面向对象软件开发考查的重要内容。 
    【问题1】
        本题主要考查用例图。
        用例之间的关系主要有以下三种:
        (1)包含关系。当可以从两个或两个以上的用例中提取公共行为时,应该使用包含关系来表示它们。用《include》表示。
        (2)扩展关系。如果一个用例明显地混合了两种或两种以上的不同场景,即根据情况可能发生多种分支,则可以将这个用例分为一个基本用例和一个或多个扩展用例,这样使描述可能更加清晰。用《extend》表示。
        (3)泛化关系。当多个用例共同拥有一种类似的结构和行为的时候,可以将它们的共性抽象成为父用例,其他的用例作为泛化关系中的子用例。
        在本题中,从题目的描述中,我们不难看出,用例图中缺失的用例有“使用常规卡行驶”和“使用单次卡行驶”,那么U1和U2具体对应哪个用例,我们根据题目说明,并结合用例图来看,“使用季卡行驶”与U1是泛化关系,由此可知U1应该是“使用常规卡行驶”,而U2是“使用单次卡行驶”,根据题目描述“单次卡的使用流程与季卡类似,但还需要在行程的起点和终点上检查行驶路线是否符合该卡所规定的行驶路线”,由此可知,U1是对“使用季卡行驶”的扩展,由此第1空应填《extend》。
    【问题2】
        本问题考查类图。对于这个题目,我们应该结合题目的描述及给出的类图来求解。根据题目的描述,本系统包含的类主要有路段( Road Segment)、地理坐标点(Node)、访问控制(Access Control)设备、自动扫描行驶卡(Card)、行程(Trajectory)、常规卡(Regular Card)、季卡( Season Card)、单次卡(Minitrip Card)、预付卡(Prepaid Card)和客户(Customer)等。
        从类图中C1与类Node的关系和C2与AccessControlNode的关系,再结合题目描述“路段由两个地理坐标点(Node)标定”可以知道C1应该是路段类,而由题目描述“行程(Trajectory)由一组连续的路段构成。行程的起点(Entry)和终点(Exit)都装有访问控制设备”可以知道C2应该是行程(Trajectory)类。
        而从类图看,C4和C5是继承于C3的,再结合类图中C3与客户类和行程类的关系,可知C3应该是一切卡的抽象类,因此是自动扫描行驶卡(Card),而C5是C6和季卡的父类,再根据题目描述“季卡和单次卡都是预付卡(PrepaidCard)”可知C5是预付卡(PrepaidCard),而C6是单次卡(MinitripCard),而C4是常规卡(RegularCard)。
        在UML中,多重度又称重复度,多重度表示为一个整数范围n..m,整数n定义所连接的最少对象的数目,而m则为最多对象数(当不知道确切的最大数时,最大数用*号表示)。最常见的多重性有0..1、0..*、1..1和1..*,而*与0..*是等价的。
        空(2)和(3)描述的是客户与卡之间的多重度,题目告诉我们系统有三种卡,因此一个客户最多可以持有这三种卡,因此空(3)应填1..3。而一个卡只能被一个客户持有,因此客户这端应该填1。
    【问题3】
        根据题目描述,RoadSegment类应该包含的关键属性是里程数(Distance),因为这能标识一个路段的长度;而Trajectory类应该包含的关键属性是起点(Entry)、终点(Exit)、进入时间(Date Of Entry),这样才能说明某一次行程是何时从哪里开始到那里结束的;而Card类的关键属性应包含有效期(Valid Period)和里程单价( Unit Price)。

第 4 题

【说明】
设某一机器由n个部件组成,每一个部件都可以从m个不同的供应商处购得。供应商j供应的部件i具有重量wij和价格cij。设计一个算法,求解总价格不超过上限cc的最小重量的机器组成。
采用回溯法来求解该问题:
首先定义解空间。解空间由长度为n的向量组成,其中每个分量取值来自集合{1,2,…,m},将解空间用树形结构表示。
接着从根结点开始,以深度优先的方式搜索整个解空间。从根结点开始,根结点成为活结点,同时也成为当前的扩展结点。向纵深方向考虑第一个部件从第一个供应商处购买,得到一个新结点。判断当前的机器价格(c11)是否超过上限(cc),重量(w11)是否比当前已知的解(最小重量)大,若是,应回溯至最近的一个活结点;若否,则该新结点成为活结点,同时也成为当前的扩展结点,根结点不再是扩展结点。继续向纵深方向考虑第二个部件从第一个供应商处购买,得到一个新结点。同样判断当前的机器价格(c11+c21)是否超过上限(cc),重量(w11+w21)是否比当前已知的解(最小重量)大。若是,应回溯至最近的一个活结点;若否,则该新结点成为活结点,同时也成为当前的扩展结点,原来的结点不再是扩展结点。以这种方式递归地在解空间中搜索,直到找到所要求的解或者解空间中已无活结点为止。
 

【C代码】
下面是该算法的C语言实现。
(1)变量说明
n:机器的部件数
m:供应商数
cc:价格上限
w[][]:二维数组,w[i][j]表示第j个供应商供应的第i个部件的重量
c[][]:二维数组,c[i][j]表示第j个供应商供应的第i个部件的价格
bestW:满足价格上限约束条件的最小机器重量
bestC:最小重量机器的价格
bestX[]:最优解,一维数组,bestX[i]表示第i个部件来自哪个供应商
cw:搜索过程中机器的重量
cp:搜索过程中机器的价格
x[]:搜索过程中产生的解,x[i]表示第i个部件来自哪个供应商
i:当前考虑的部件,从0到n - 1
j:循环变量
(2)函数backtrack
int n = 3;
int m = 3;
int cc = 4;
int w[3][3] = { {1,2,3},{3,2,1},{2,2,2} };
int c[3][3] = { {1,2,3},{3,2,1},{2,2,2} };
int bestW = 8;
int bestC = 0;
int bestX[3] = {0,0,0};
int cw = 0;
int cp = 0;
int x[3] = {0,0,0};
int backtrack(int i){
    int j = 0;
   int found = 0;
   if(i > n - 1){  /*得到问题解*/
       bestW = cw;
    bestC = cp;
    for(j = 0; j < n; j++){
            (1)  ;
    }
return 1;
   }
   if(cp <= cc){ /*有解*/
       found = 1;
   }
   for(j = 0;    (2)    ; j++){
      /*第i个部件从第j个供应商购买*/
(3)    ;
    cw = cw + w[i][j];
    cp = cp + c[i][j];
if(cp <= cc && (4)    ){ /*深度搜索,扩展当前结点*/
        if(backtrack(i + 1)){   found = 1;  }
    }
   /*回溯*/
    cw = cw - w[i][j];
         (5) ;
   }
   return found;
}
 

答案与解析

  • 试题难度:较难
  • 知识点:数据结构与算法应用>回溯法
  • 试题答案:

    (1)bestX[j] = x[j]
    (2)j < m
    (3)x[i] = j
    (4)cw < bestW
    (5)cp = cp - c[i][j]
     

  • 试题解析:

        本题考查回溯法的应用。
        在题目的描述中告诉了我们回溯法的基本思想。其实回溯法主要有两个过程,一个是向前探索,只要在当前满足设定的判定条件时,才向前探索,而另外一个就是回溯,在两种情况下,需要回溯,其分别是当不满足设定条件时和求的一个解的时候。
        下面我们来具体分析本试题。根据题目给出的注释,我们知道第(1)空所处的位置是得到问题的一个解时,我们该怎么办,根据题目描述,应该是将这个解记录下来,存放到bestX数组当中,而求得的解是保存在x数组当中的,因此这里需要循环将x数组中的元素值赋给bestX数组,因此第(1)空答案为bestX[j] = x[j]。
        第(2)空是for循环中的循环判定条件,根据题目注释我们知道该循环的作用是确定第i个部件从第j个供应商购买,那么在确定第i个部件到底是从哪个供应商购买时,需要比较从各供应商购买的情况,因此循环的次数为供应商数,因此第(2)空答案是j < m。结合这个循环体当中的语句和我们对回溯法的理解,我们可以发现循环下面的语句是要考虑将第i个部件从供应商j当中购买,也就是j是当前解的一部分,因此需要将j记录到解当中来,所以第(3)空应该是x[i] = j。
        第(4)空是if语句中的一个条件,根据题目注释,我们可以知道如果该if语句表达式的计算结果为真,需要进行深度搜索,扩展当前结点,那么如果要继续向前探索,就需要满足设定的条件,也就是当前总重量要小于bestW,而当前总价格要小于等于cc,因此第(4)空的答案应该填cw < bestW。
        根据题目注释,第(5)空是在回溯下面的语句,根据回溯的原则我们可以知道,回溯时,要将当前考虑的结点的重量和价格从总重量和总价格中减去,因此第(5)的答案是cp = cp - c[i][j]。

第 5 题

【说明】
某大型商场内安装了多个简易的纸巾售卖机,自动出售2元钱一包的纸巾,且每次仅售出一包纸巾。纸巾售卖机的状态图如图5-1所示。

采用状态(State)模式来实现该纸巾售卖机,得到如图5-2所示的类图。其中类State为抽象类,定义了投币、退币、出纸巾等方法接口。类SoldState、SoldOutState、NoQuarterState和HasQuarterState分别对应图5-1中纸巾售卖机的4种状态:售出纸巾、纸巾售完、没有投币、有2元钱。

【C++代码】
#include <iostream>
using namespace std;
// 以下为类的定义部分
class TissueMachine;   // 类的提前引用
class State {
public:
   virtual void insertQuarter() = 0;  //投币
   virtual void ejectQuarter() = 0;    //退币
   virtual void turnCrank()= 0;   //按下“出纸巾”按钮
   virtual void dispense() = 0;    //出纸巾
};
/* 类SoldOutState、NoQuarterState、HasQuarterState、SoldState的定义省略,每个类中均
定义了私有数据成员TissueMachine* tissueMachine; */
class TissueMachine {
private:
     (1)   *soldOutState, *noQuarterState, *hasQuarterState,*soldState, *state ;
   int count; //纸巾数
public:
  TissueMachine(int numbers);
  void setState(State* state);
  State* getHasQuarterState();
  State* getNoQuarterState();
  State* getSoldState();
  State* getSoldOutState();
  int getCount();
  // 其余代码省略
};
// 以下为类的实现部分
void NoQuarterState ::insertQuarter() {
    tissueMachine->setState(  (2)  );
}
void HasQuarterState ::ejectQuarter() {
    tissueMachine->setState(  (3)  );
}
void SoldState ::dispense() {
    if(tissueMachine->getCount() > 0) {
  tissueMachine->setState(  (4)  );
    }
    else {
  tissueMachine->setState(  (5)  );
    }
}  // 其余代码省略

答案与解析

  • 试题难度:较难
  • 知识点:面向对象程序设计>C++程序设计
  • 试题答案:

    (1)State
    (2)tissueMachine->getHasQuarterState()
    (3)tissueMachine->getNoQuarterState()
    (4)tissueMachine->getNoQuarterState()
    (5)tissueMachine->getSoldOutState()
     

  • 试题解析:

        本题考查基本面向对象设计模式的运用能力。
        状态设计模式主要是能够使一个对象的内在状态改变时允许改变其行为,使这个对象看起来像是改变了其类。由类图可知类State是类SoldState、SoldOutState、NoQuarterState和HasQuarterState的父类,它抽象了这四个类的共有属性和行为。在使用中,无论是这四个类中那个类的对象,都可被当作State对象来使用。
        而根据题目的描述,我们可以知道一个纸巾售卖机它由4种状态,分别是售出纸巾、纸巾售完、没有投币、有2元钱。
        在本题中,根据程序我们不难知道第(1)空是要定义5个对象指针,而这些对象指针都应该属于State类型,因此第一空答案为State。
        而第(2)在类NoQuarterState(没有投币)的insertQuarter()函数中,而这个函数是投币函数,在该函数中,使用了tissueMachine类的setState方法,该方法是设置纸巾售卖机的当前状态,根据题目给出的纸巾售卖机状态图,我们可以知道,从没有投币状态,经过投币后,应该转换到有2元钱状态。而setState方法的参数是一个State的对象,因此第(2)空应该是一个有2元钱对象,而这里我们可以新创建一个该对象,也可以通过tissueMachine类的getHasQuarterState方法来获得这样一个对象,所以第(2)空答案应该是“tissueMachine->getHasQuarterState()”或“new HasQuarterState”。
        而第(3)在类HasQuarterState(有2元钱)的ejectQuarter()函数中,而这个函数是退币函数,在该函数中,也使用了tissueMachine类的setState方法,该方法是设置纸巾售卖机的当前状态,根据题目给出的纸巾售卖机状态图,我们可以知道,从有2元钱状态,经过退币后,应该转换到没有投币状态。而setState方法的参数是一个State的对象,因此第(3)空应该是一个没有投币对象,而这里我们可以新创建一个该对象,也可以通过tissueMachine类的getNoQuarterState方法来获得这样一个对象,所以第(3)空答案应该是“tissueMachine-> getNoQuarterState()”或“new NoQuarterState”。
        而同样的道理,我们可以知道第(4)空的答案是“tissueMachine->getNoQuarterState()”或“new NoQuarterState”。第(5)空的答案是“tissueMachine->getSoldOutState()”或“new SoldOutState”。

第 6 题

【说明】
某大型商场内安装了多个简易的纸巾售卖机,自动出售2元钱一包的纸巾,且每次仅售出一包纸巾。纸巾售卖机的状态图如图6-1所示。

采用状态(State)模式来实现该纸巾售卖机,得到如图6-2所示的类图。其中类State为抽象类,定义了投币、退币、出纸巾等方法接口。类SoldState、SoldOutState、NoQuarterState和HasQuarterState分别对应图6-1中纸巾售卖机的4种状态:售出纸巾、纸巾售完、没有投币、有2元钱。

 

【Java代码】
import java.util.*;
interface State {
  public void insertQuarter();    //投币
  public void ejectQuarter();    //退币
  public void turnCrank();   //按下“出纸巾”按钮
  public void dispense();   //出纸巾
}
class TissueMachine {
    (1)   soldOutState, noQuarterState, hasQuarterState, soldState, state;
  state = soldOutState;
  int count = 0;    //纸巾数
  public TissueMachine(int numbers) {  /* 实现代码省略 */ }
  public State getHasQuarterState()  {  return hasQuarterState;  }
  public State getNoQuarterState()   {  return noQuarterState;  }
  public State getSoldState()    {  return soldState;   }
  public State getSoldOutState() {  return soldOutState;    }
  public int getCount()   {  return count;  }
// 其余代码省略
}
 
class NoQuarterState implements State {
   TissueMachine tissueMachine;
  public void insertQuarter() {
    tissueMachine.setState(  (2)  );
  } 
//构造方法以及其余代码省略
}
class HasQuarterState implements State {
   TissueMachine tissueMachine;
  public void ejectQuarter() { 
    tissueMachine.setState(  (3)  );
  }
//构造方法以及其余代码省略
}
class SoldState implements State {
  TissueMachine tissueMachine;
  public void dispense() {
    if(tissueMachine.getCount() > 0)  {
 tissueMachine.setState(  (4)  );
    } else {
  tissueMachine.setState(  (5)  );  }
    }
}

答案与解析

  • 试题难度:较难
  • 知识点:面向对象程序设计>Java程序设计>状态模式
  • 试题答案:

    (1)State
    (2)tissueMachine.getHasQuarterState()
    (3)tissueMachine.getNoQuarterState()
    (4)tissueMachine.getNoQuarterState()
    (5)tissueMachine.getSoldOutState()

  • 试题解析:

        本题考查基本面向对象设计模式的运用能力。
        状态设计模式主要是能够使一个对象的内在状态改变时允许改变其行为,使这个对象看起来像是改变了其类。由类图可知类State是类SoldState、SoldOutState、NoQuarterState和HasQuarterState分的父类,它抽象了这四个类的共有属性和行为。在使用中,无论是这四个类中那个类的对象,都可被当作State对象来使用。
        而根据题目的描述,我们可以知道一个纸巾售卖机它由4种状态,分别是售出纸巾、纸巾售完、没有投币、有2元钱。
        在本题中,根据程序我们不难知道第(1)空是要定义5个对象的引用,而这些变量都应该属于State类型,因此第一空答案为State。
        而第(2)在类NoQuarterState(没有投币)的insertQuarter()函数中,而这个函数是投币函数,在该函数中,使用了tissueMachine类的setState方法,该方法是设置纸巾售卖机的当前状态,根据题目给出的纸巾售卖机状态图,我们可以知道,从没有投币状态,经过投币后,应该转换到有2元钱状态。而setState方法的参数是一个State的对象,因此第(2)空应该是一个有2元钱对象,而这里我们可以新创建一个该对象,也可以通过tissueMachine类的getHasQuarterState方法来获得这样一个对象,所以第(2)空答案应该是“tissueMachine.getHasQuarterState()”或“new HasQuarterState”。
        而第(3)在类HasQuarterState(有2元钱)的ejectQuarter()函数中,而这个函数是退币函数,在该函数中,也使用了tissueMachine类的setState方法,该方法是设置纸巾售卖机的当前状态,根据题目给出的纸巾售卖机状态图,我们可以知道,从有2元钱状态,经过退币后,应该转换到没有投币状态。而setState方法的参数是一个State的对象,因此第(3)空应该是一个没有投币对象,而这里我们可以新创建一个该对象,也可以通过tissueMachine类的getNoQuarterState方法来获得这样一个对象,所以第(3)空答案应该是“tissueMachine. getNoQuarterState()”或“new NoQuarterState”。
        而同样的道理,我们可以知道第(4)空的答案是“tissueMachine.getNoQuarterState()”或“new NoQuarterState”。第(5)空的答案是“tissueMachine.getSoldOutState()”或“new SoldOutState”。

results matching ""

    No results matching ""