前面说过了,在Java类库中设计模式的踪影随处可见,因而要讲解所有出现的模式
实在是不可能,这儿主要把焦点聚集在AWT/Swing中,管中窥豹,却也可以了解设计模式
的一些深刻的含义所在。
2.5 Command模式和Action接口(3月14日)
在Swing中摒弃了原有的老的AWT基于继承的事件模型,而根据Stragety模式引入新
的基于授权的事件模型。在这种模型中,事件处理涉及到三个方面:构件,事件和监听
器(Listener),由构件激发事件,在由事件监听器接受并处理事件。
所有的行动类事件监听器都要实现ActionListener接口,在ActionListener中只定
义了一个actionPerformed()方法,对与每个注册了这个监听器的组件,当其中发生了行
动类事件(比如按钮按下)时,就会调用actionPerformed()方法来响应事件。但是当多
个事件共享一个操作的时,比如,很多时候都需要为一个快捷键,一个工具栏上的按钮
,一个菜单项设置相同的处理函数,如果用ActionListner的话,就要分别为这三类事件
注册三个不同的事件监听器,很是麻烦(因为这三种事件需要不同的监听器来接受,但
是这三种监听器都是ActionListner的子接口,因而理论上可以用一个实现了ActionLis
tner的类来代替这三个接口,但是我没有试验过是否可行)。Swing中为了避免麻烦,引
入了Action接口。
Action实际上是ActionListener的子接口,扩展了ActionListener用来处理同一个
事件响应过程要被多个事件激发的情况。当然Action中还包含了一些其它的有用的东西
,比如可以包含多个行动描叙和图标,但是在这儿我们讨论的只是Action接口中所体现
的Command模式。
Command模式将请求封装为一个对象,这种封装可以带来很多的好处,比如可以让你
用不同的请求来对客户进行参数化。还有用的很多的,比如用Ctrl+Z实现撤销,用Ctrl
+Y进行重做等等,都可以用Command模式轻松实现。
Command模式体现了一种高度抽象的面向对象的建模方法,确实应该值得好好注意。
下面给出了Command模式的类图:
首先需要为Invoker对象注册一个实现了Command接口的ConcreteCommand对象,当事
件促发时,Invoker根据Command接口来对ConcreteCommand进行请求调用,而ConcreteC
ommand对象则需要协同Receiver对象一起来完成这个请求。上面就是这个模式所包含的
对象之间的协作关系。如果你的Swing的事件模型比较了解的话,那么就会发现,这和那
个事件模型其实没有什么实质上的分别。