简单监听器

监听器模式:
事件监听器是经常可以遇到的一种设计模式,一般用在这样一种场景下:
当模块的一部分A在完成后需要通知其他的软件模块B,而等待通知的模
块B在事先不需要采用轮询的方式来查看另一个模块A是否通知自己。即,
当某事件发生,则监听器立刻就知道了该事件。

接口的设计:
我们需要一个对事件(event)的抽象,同样需要一个对监听器(listener)的抽象。
EventSource.java是事件源的接口,只需要提供一个可以获取事件类型的方法即可
EventListener.java监听器接口,提供一个当事件发生后的处理方法即可

项目的目录结构:

EvenListener.java文件内容:

package com.listener.framework;

/**
 * 事件监听器接口.
 */
public interface EventListener {
	/**
	 * 根据事件源实例的不同状态,来确定相应的响应.
	 * @param event 事件源实例.
	 */
	void handleEvent(EventSource event);
}

EventSource.java文件内容:

package com.listener.framework;

/**
 * 事件源接口.
 */
public interface EventSource {
	/**
	 * 事件类型1.
	 */
	public final int EVENT_TIMEOUT = 1;
	/**
	 * 事件类型2.
	 */
	public final int EVENT_OVERFLOW = 2;
	
	/**
	 * 获取事件类型.
	 * @return 事件类型
	 */
	int getEventType();
}

Timer.java文件内容:

package com.listener.framework.impl;

import com.listener.framework.EventListener;

/**
 * 定时器.
 */
public class Timer extends Thread {
	/**
	 * 监听器.
	 */
	private EventListener listener;
	/**
	 * 定时毫秒数.
	 */
	private int sleepSeconds;
	/**
	 * 无参构造方法.
	 */
	public Timer(){
	}
	
	/**
	 * 实例化定时seconds毫秒的定时器.
	 * @param seconds 毫秒数.
	 */
	public Timer(int seconds){
		this.sleepSeconds = seconds;
	}
	
	/**
	 * 设置监听器.
	 * @param listener 监听器.
	 */
	public void setEventListener(EventListener listener){
		this.listener = listener;
	}

	@Override
	public void run() {
		for(int i = sleepSeconds; i > 0; i--){
			try {
				System.out.println("Timer.run()");
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				System.err.println(e.getMessage());
			}
		}
		//当sleepSeconds过后,事件源向所注册的监听器发送事件对象
		raiseTimeoutEvent();
		
	}
	
	/**
	 * 唤醒timeout事件.
	 */
	private void raiseTimeoutEvent(){
		//raise一个TimeOut事件给监听器
		this.listener.handleEvent(new TimeOutEvent());
	}
	
	
}


TimeOutEvent.java文件内容:

package com.listener.framework.impl;

import com.listener.framework.EventSource;

/**
 * 超时事件.
 */
public class TimeOutEvent implements EventSource {
	/**
	 * 事件类型.
	 */
	private int type;
	/**
	 * 实例化超时事件.
	 */
	public TimeOutEvent(){
		this.type = EventSource.EVENT_TIMEOUT;
	}
	/**
	 * 获取事件类型.
	 */
	public int getEventType() {
 		return this.type;
	}

}


TimeListenerTester.java文件内容:

package com.listener.framework.impl;

import com.listener.framework.EventListener;
import com.listener.framework.EventSource;

/**
 * 我们假设这样一个场景:一个定时器T, 先设置这个定时器的时间为t,当t到时后,则触发一个超时事件
 * 在类EventListenerTester的execute()方法中,我们先设置一个定时器,这个定时器初始化为3秒,设置好定时器后,
 * 程序进入一个while(true)循环中,当定时器到时后,它会发送一个timeout事件给当前线程Tester,
 * 此时我们可以设置execute中的while条件为false,退出死循环。
 */
public class EventListenerTester implements EventListener {

	private boolean loop = true;

	public void execute() {
		// 创建定时器timer
		Timer timer = new Timer(3);
		// 为定时器注册监听器this
		timer.setEventListener(this);
		//定时器启动,当3秒之后,定时器向监听器发送事件
		timer.start();
		//监听器会调用handleEvent(EventSource event)方法来根据定时器所发送过来的事件对象做出相应的响应
		try {
			while (loop) {
				Thread.sleep(1000);
				System.out.println("still in while(true) loop");
			}
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		System.out.println("interupted by time out event");
	}

	// 监听器根据事件对象信息中传来的信息来确定对事件的响应
	@Override
	public void handleEvent(EventSource event) {
		int eType = event.getEventType();

		switch (eType) {
		case EventSource.EVENT_TIMEOUT:
			this.loop = false;
			break;
		case EventSource.EVENT_OVERFLOW:
			break;
		default:
			this.loop = true;
			break;
		}
	}
	/**
	 * 测试.
	 * @param args
	 */
	public static void main(String[] args) {
		EventListenerTester tester = new EventListenerTester();
		tester.execute();
	}
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值