《java与模式》学习系列——责任链模式

 

一、 责任链(Chain of Responsibility)模式的结构

在责任链模式里,很多对象由每一个对象对其下家的引用而链接起来形成一条链。请求在这个链上传递,直到链上的某一个对象决定处理此请求。发出这个请求的客户端并不知道链上的哪一个对象最终处理这个请求,这使得系统可以在不影响客户端的情况下动态地重新组织链和分配责任。

如下图所示:

代码如下 :

//Handler

public abstract class Handler {

 

         protected Handler successor;

         public abstract void handleRequest();

         public void setSuccessor(Handler successor){

                   this.successor = successor;

         }

         public Handler getSuccessor(){

                   return successor;

         }

}

//ConcreteHandler

public class ConcreteHandler extends Handler {

         @Override

         public void handleRequest() {

                   if(getSuccessor()!=null){

                            System.out.println("the request is passed to " + getSuccessor());

                            getSuccessor().handleRequest();

                   }else{

                            System.out.println("The request is handler here");

                   }

         }

}

//Client

public class Client {

         static private Handler handler1,handler2;

         public static void main(String []args){

                   handler1 = new ConcreteHandler();

                   handler2 = new ConcreteHandler();

                   handler1.setSuccessor(handler2);

                   handler1.handleRequest();

         }

}

二、 责任链模式在java中的应用

java1.0版的AWT事件处理机制

Java1.0版本中的AWT库使用了责任链模式和命令模式处理GUI的事件。由于视窗构件往往位于容器构件内,因此,当事件发生在一个构件上时,此构件的事件处理器可以处理此事件,然后决定是否将事件向上级容器构件传播。上级容器构件接到事件后,可以在此处理此事件,然后决定是否将事件再次向上级容器构件传播,如此往复,直到事件到达顶层构件。

缺点:

1)、AWT 1.0事件处理模型是基于继承的。为了使一个程序能够捕捉GUI事件并处理此事件,必须继承此构件并且给其子类配备事件处理器,也就是置换掉action()方法或者handleEvent()方法。这不是应当提倡的做法:在一个面向对象的系统里,经常使用的应当是委派关系,继承关系不就当被滥用。

2)、在一个复杂的GUI系统里,这样为所有事件的构件提供子类,会导致很多的子类,增加维护成本。

3)、由于每一个事件都会沿着构件树结构向上传播,因此事件浮升机制会使得事件的处理变得较慢,这也是缺点之一。

DHTML中的事件处理

浏览器的DOM模型中的事件处理均采用责任链模式。

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

Internet Explorer的事件模型:当一个事件发生在Internet Explorer所浏览的网页中时,Internet Explorer会使用DHTML的“Event Bubbing”,即事件浮升机制处理此事件。Internet ExplorerDOM模型是HTML对象等级结构和事件处理机制。在DOM里面,每一个HTML标识符都是一个DOM对象,而每一个DOM对象都可以产生事先定义好的几个事件中的一个(或几个)。这样的一个事件首先发生在事件所属的对象上,然后向上传播,传到此对象所属的容器对象上。因此,事件浮动机制恰恰是事件捕捉机制的相反面。

另:Timer定时器

java.util.Timer类封装了定时器所需的线程功能。与此类相应的,还有一个TimerTask类,封装了当被定时的任务需要反复发生时所需的线程功能。如下图所示:

TimerTimerThread的子类,而TimerThreadThread的实现,因此TimerThread的实现。同时TimerTaskRunnable的实现,从而也是一个线程。一个例子:

public class Reminder{

         Timer timer;

         public Reminder(int seconds){

         timer = new Timer();

         timer.schedule(new RemindTask(),seconds*1000);

}

class RemindTask extends TimerTask{

         public void run(){

         System.out.println(“Time’s up”);

         //结束timer线程

timer.cancel();

}

}

}

在每一个Timer对象的背后,都有一个背景线程,用来顺序执行Timer的任务,这些任务应当迅速结束,不然就会霸占timer用来执行任务的线程,从而延迟后面的任务。当所有的任务都完成后,timer的任务执行线程就会顺利地结束并被java垃圾收集器所收集,只是垃圾收集的时间并不能预测。如果程序想要迅速地结束timer的任务执行线程,调用方法就应当调用timercancel()方法。Timer类是线程安全的,换言之,可以有多个线程共享同一个Timer对象,而不需要同步化。Timer类实际上是用Object.wait(long)方法实现定时的。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值