java

位置:IT落伍者 >> java >> 浏览文章

Java模


发布日期:2024年01月18日
 
Java模

对象的树结构

在面向对象的技术里对象的树结构是一个强有力的工具更是模式理论的一个重要的组成部分需要应用到符合模式装饰模式和迭代子模式

《墨子天志》说庶人竭力从事未得次己而为政有士政之士竭力从事未得次己而为政有将军大夫政之将军大夫竭力从事未得次己而为政有三公诸侯政之三公诸侯竭力听治未得次己而为政有天子政之天子未得次己而为政有天政之

意为恣意上面的话就是说百姓有官吏管治官吏由将军和士大夫管治将军和士大夫由三公和诸侯管治三公和诸侯由天子管治天子由天管治

墨子论责任和责任链的传播图中有阴影的对象给出了一个可能的责任链选择

当一个百姓提出要求时此要求会传达到一级再到大夫一级进而传到诸侯一级天子一级最后到一级

DHTML中的事件处理

浏览器的DOM(Document Object Model)模型中的事件处理均采用责任链模式本节首先考察Netscape浏览器的DHTML的事件处理然后再研究Internet Explorer的事件模型

Netscape的事件模型

Netscape的事件处理机制叫做事件捕捉(Event Capturing)在事件捕捉机制里面一个事件是从DOM的最高一层向下传播也就是说window对象是第一个接到事件的然后是document对象如此往下事件的产生对象反而是最后一个接到事件的

如果要是一个对象捕获某一个事件只需要调用captureEvent()方法如果要使一个对象把某一个事件向下传而不处理此事件只需要对此对象使用releaseEvents方法即可下面考察一个简单的事件捕获和传递的例子

一个Netscape的例子

在这个例子里有一个textbox和两个button一个叫做Capture Event单击后会使网页的click事件被捕捉文字框中的计数会加一另一个叫做Release Event单击后会使网页的click事件不被捕捉

使click事件被捕捉需要调用captureEvent()方法而使click事件不被捕捉需要调用releaseEvent()方法下面是具体的html和JavaScript代码

代码清单JavaScript和HTML源代码

显然一个事件可以在几个不同的等级上得到处理这是一个不纯的责任链模式

Internet Explorer的事件模型

Internet Explorer处理事件的方式与Netscape既相似又不同当一个事件发生在Internet Explorer所浏览的网页中时Internet Explorer会使用DHTML的Event Bubbling即事件浮升机制处理此事件Internet Explorer的DOM模型是html对象等级结构和事件处理机制在DOM里面每一个html标示都是一个DOM对象而每一个DOM对象都可以产生事先定义好的几个事件中的一个(或几个)这样的一个事件会首先发生在事件所属的对象上然后向上传播传到此对象所属的容器对象上如此等等因此事件浮升机制恰恰是事件捕捉机制的相反面

在Event Bubbling机制里面产生事件的对象首先会收到事件然后事件会依照对象的等级结构向上传播比如一个DIV里有一个FormForm里面又有一个Button那么当Button的onclick事件产生时Form的onclick事件代码就会被执行然后事件就会传到DIV对象如果DIV对象的onclick事件有任何代码的话这代码就会被执行然后事件继续沿着DOM结构上行

如果要阻止事件继续向上传播可以在事件链的任何一个节点上把cancelBubble性质设置成True即可

Internet Explorer 浏览器几乎为所有的 HTML 标识符都提供了事件句柄因此Internet Explorer不需要captureEvents()方法和releaseEvents()方法来捕获和释放事件下面的JavaScript语句指定了document对象的onclick事件的处理方法

documentonclick = functionName;

而下面的语句则停止了document对象对onclick事件的处理

documentonclick = null;

因为事件处理性质被赋值nulldocument便没有任何的方法处理此事件换言之null值禁止了此对象的事件处理这种方法可以用到任何的对象和任何的事件上面当然这一做法不适用于Netscape

与Netscape中一样一个事件处理方法可以返还Boolean值比如单击一个超链接标记符是否造成浏览器跟进取决于此超链接标记符的onclick事件是否返还true

为了显示Internet Explorer中的事件浮升机制本节特准备了下面的例子一个Form里面有一个Button请见下图

一个Internet Explorer的例子

其HTML代码请见下面

代码清单JavaScript和HTML源代码

当myButton的onclick事件发生时myButton的事件处理首先被激发从而显示出如下的对话窗

myButton对象的事件处理被激发

然后事件会象气泡一样浮升到上一级的对象即myForm对象上myForm对象的事件处理给出下面的对话窗

myFormn对象的事件处理被激发

这以后事件继续浮升到更上一级的对象即body上这时document对象的事件处理被激发并给出下面的对象窗

document对象的事件处理被激发

这就是事件浮升(Event Bubbling)机制

显然这三级对象组成一个责任链而事件便是命令或请求当事件沿着责任链传播时责任链上的对象可以选择处理或不处理此事件不论事件在某一个等级上是否得到处理事件都可以停止上浮或继续上浮这是不纯的责任链模式

责任链模式与其它模式的关系

责任链模式与以下的设计模式相关

复合模式(Composite Pattern) 当责任链模式中的对象链属于一个较大的结构时这个较大的结构可能符合复合模式

命令模式(Command Pattern) 责任链模式使一个特定的请求接收对象对请求或命令的执行变得不确定而命令模式使得一个特定的对象对一个命令的执行变得明显和确定

模版方法模式(Template Method) 当组成责任链的处理者对象是按照复合模式组成一个较大的结构的责成部分的话模版方法模式经常用来组织单个的对象的行为

问答题

第一题在称为拱猪的纸牌游戏中四个参加者中由牌的可以选择一个时机放出这张牌放出后四个人中的一个会不可避免地拿到这张

请使用责任链模式说明这一游戏并给出UML结构图

第二题《墨子迎敌祠》里描守城军队的结构城上步一甲一戟其赞三人五步有伍长十步有什长百步有佰长旁有大帅中有大将皆有司吏卒长

一个兵勇需要上级批准以便执行一项任务他要向伍长请求批准伍长如果有足够的权限便会批准或驳回请求如果他没有足够的权限便会向上级即什长转达这个请求什长便会重复同样的过程直到大将那里一个请求最终会被批准或驳回然后就会象下传直到传回到发出请求的士兵手里

有些请求会很快返回有些则要经过较长的过程请求到底由谁批准事前并不知道请求的处理者并不是固定的有些军官会晋升转业或从别的单位转过来等等

请使用责任链模式解释这个核准请求的结构

(本例子受到文献[ALPERT]里Chain of Responsibility一节所给出的一个例子的启发

第三题王羲之在《兰亭序》中写道有清流激湍映带左右引以为流觞曲水列坐其次讲的是大伙列坐水畔随水流放下带羽毛的酒杯饮酒远道而来的酒杯流到谁的面前谁就取而饮之

在这个活动中参加者做成一排面对着一条弯曲的小溪侍者把酒杯盛满酒让酒杯沿着小溪向下漂流酒杯漂到一个参加者面前的时候他可以选择取酒饮之也可以选择让酒杯漂向下家

假设每一杯酒最终都会被参加者中之一喝掉那么这个游戏是不是纯的责任链模式?

问答题答案

第一题答案这是一个纯的责任链模式

首先牌放出之后每个人都只能要么躲过要么吃住牌便是责任链模式中的请求四个人便是四个处理者对象组成责任链

每一个参加者的行为不仅仅取决于他手中的牌而且取决于他是否想得一个想收全红的人可能会权力揽一个不想收全红的人一般不想收除非他想阻止别人收因为一旦有人收全红另外三个人就会复出较大的代价因此阻止别人收全红的动机会促使一个参与者主动收有的时候放出牌的人也会想要得牌而得不到有的时候放出牌的人想要害人但却害了自己

这就是说到底是四个人中的哪一个人得到牌是完全动态决定的

系统的UML结构图如下

纸牌游戏拱猪的UML类图

由于玩牌的时候可能有四人位置的任意调换或者有候补者在旁等待一旦在任的玩家被淘汰便可上任这样四个人组成的牌局是动态变化的同时因为谁会拿到牌在每一局均会不同因此谁会放出牌也是动态的

因此责任链的组成和顺序变不是一成不变的而是动态的和变化的

第二题答案墨子的守城部队的等级结构可以用下面的对象图表示               

上一篇:Java中的模式--单态

下一篇:深入浅出Java设计之备忘录模式