【问题1】
(1) abstract
(2) null
(3) List
(4) childList
(5) printTree(file)
•类Component为组合中的对象声明接口,在适当的情况下,实现所有类共有接口的缺省行为,声明一个接口用于访问和管理Component的子部件:
•类Leaf在组合中表示叶节点对象,叶节点没有子节点;并在组合中定义图元对象的行为;
•类Composite定义有子部件的那些部件的行为,存储子部件,并在Component 接口中实现与子部件有关的操作;
•类Client通过Component接口操纵组合部件的对象。
状态模式
试题六(状态模式)
某大型商场内安装了多个简易的纸巾售卖机,自动出售2元钱一包的纸巾,且每次仅售出一包纸巾。纸巾售卖机的状态图如图6-1所示。
采用状态(State)模式来实现该纸巾售卖机,得到如图6-2所示的类图。其中类State为抽象类,定义了投币、退币、出纸巾等方法接口。类SoldState、SoldOutState、 NoQuarterState和HasQuarterState分别对应图6-1中纸巾售卖机的4种状态:售出纸巾、纸巾售完、没有投币、有2元钱。
【问题1】
(1)State
(2)tissueMachine.getHasQuarterStat()
(3)tissueMachine.getNoQuarterState()
(4)tissueMachine.getNoQuarterState()
(5)tissueMachine.getSoldOutState()
分析
要点:要充分理解状态图的转换关系,状态转换的条件确定出当前状态及下一状态
本题考查状态(State)模式的概念及应用。
状态模式是一种对象的行为型模式,允许一个对象在其内部状态改变时改变它的行为,对象看起来似乎修改了它的类。状态模式的类图如下所示:
状态模式主要解决的是控制一个对象转换的条件表达式过于复杂的情况。把状态的判断逻辑转移到表示不同状态的一系列类当中,可以把复杂的判断逻辑简化。状态模式的好处是将与特定状态相关的行为局部化,并且将不同状态的行为分割开来。
题目利用状态模式来实现一个简易的纸巾售卖机。售卖机的状态转换图已经在题目中给出,类SoldState、SoldOutState、NoQuarterState 和 HasQuarterState 分别用来表示售卖机的4种不同状态,对应于状态模式中的ConcreteState1,...ConcreteStateN。题目所
设置的填空,主要集中在状态转换上。因此解答该题时,要求在理解状态模式内涵的基础上,依据纸巾售卖机的状态转换原则,给出正确的状态设置。
- 空(1)出现在类TissueMachine的数据成员定义部分。状态模式封装了状态的转换过程,但是它需要枚举可能的状态,因此需要实现确定状态种类。因此在类TissueMachine 中需定义出所有可能的状态对象。根据所给出的对象名称及说明中的描述,可知(1)处 应填入的类名为State。
- 空(2)〜(5)要求填写类TissueMachine中的方法setState在不同调用处的实际参数。这里的一个难点在于题目中没有显示地给出方法setState的原型及语义,这要求考生根据面向对象程序设计风格及说明中给出的应用场合来推断setState的内涵及原型,主要是确定其参数列表。
- 在面向对象程序设计中,为了做到封装,通常都会把数据成员定义为私有的。私有的数据成员对象不能直接访问,因此在类中都会提供2组访问私有数据成员的方法,分别为get...方法和set...方法(…代表对应的数据成员名称)。get...方法表示获取私有数据成员的值,其返回值类型为对应的数据成员的类型;set...方法表示对数据成员进行赋值,所要赋的值通常通过参数传递进去,方法的返回值类型通常为void。根据面向对象 程序设计的这些特点,以及状态模式的内涵及应用场合,可以推断出setState方法的功能就是设置纸巾售卖机的当前状态。纸巾售卖机在任一时刻只能处于一个唯一的状态, 由状态模式可知,纸巾售卖机的状态都是用状态对象表示的,由此就可以确定出,setState 方法的参数只要一个就可以了,就是表示纸巾售卖机下一状态的状态对象。
- 经过以上分析之后,可以明确空(2)〜(5)空所填的内容都应与状态转换相关。因此要填充这些空,只要对照图5-1的状态转换图,根据状态转换的条件确定出当前状态及下一状态即可。
- 空(2)出现在方法insertQuarter内,即给纸巾售卖机投入2元钱。根据状态图,“投入2元钱”之后,售卖机应转换到“有2元钱”的状态。“有2元钱”对应的状态的类为“HasQuarterState”,所以空(2)处应填写类HasQuarterState的对象。由此得出(2)应填 tissueMachine.getHasQuarterState()。
- 同理,空(3)表示的状态是从“有2元钱”状态,经历“退回2元钱”事件之后 的状态,及“没有投币”状态。所以空(3)处应填tissueMachine.getNoQuarterState()。
- 空(4)和(5)处分别表示卖出一包纸巾之后,售卖机应该转换到的下一个状态。 这个跟售卖机中的纸巾数有关,如果还有纸巾,则转换到“没有投币”状态,如果没有纸巾了,则转换到“纸巾售完”状态,因此,空(4)处应填tissueMachine.getNoQuarterState(),空(5)处应填tissueMachine.getSoldOutState()。