本文共 7944 字,大约阅读时间需要 26 分钟。
一、概述
childe类中的是关联监听者dad的,若要再增加监听者,会很不方便,且要修改代码。好的方法是封装监听者类,用addListener()方法动态添加监听者
二、代码
1.Test.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 | class WakenUpEvent{ private long time; private String location; private Child source; public WakenUpEvent( long time, String location, Child source) { super (); this .time = time; this .location = location; this .source = source; } public long getTime() { return time; } public void setTime( long time) { this .time = time; } public String getLocation() { return location; } public void setLocation(String location) { this .location = location; } public Child getSource() { return source; } public void setSource(Child source) { this .source = source; } } class Child implements Runnable { private List<WakenUpListener> wakenUpListeners = new ArrayList<WakenUpListener>(); public void addWakenUpListener(WakenUpListener wul){ wakenUpListeners.add(wul); } public void wakeUp(){ for ( int i = 0 ; i < wakenUpListeners.size(); i++){ WakenUpListener l = wakenUpListeners.get(i); l.actionToWakenUp( new WakenUpEvent(System.currentTimeMillis(), "bed" , this )); } } @Override public void run() { try { Thread.sleep( 3000 ); } catch (Exception e) { e.printStackTrace(); } wakeUp(); } } interface WakenUpListener { public void actionToWakenUp(WakenUpEvent e); } class Dad implements WakenUpListener { public void actionToWakenUp(WakenUpEvent e) { System.out.println( "Fedd the child" ); } } class GrandFather implements WakenUpListener { public void actionToWakenUp(WakenUpEvent e) { System.out.println( "抱孩子" ); } } public class Test { public static void main(String[] args) { Child c = new Child(); c.addWakenUpListener( new Dad()); c.addWakenUpListener( new GrandFather()); new Thread(c).start(); } } |
三、运行结果
典型应用:事件监听器
转自:http://www.cnblogs.com/java-my-life/archive/2012/05/16/2502279.html
在阎宏博士的《JAVA与模式》一书中开头是这样描述观察者(Observer)模式的:
观察者模式是对象的行为模式,又叫发布-订阅(Publish/Subscribe)模式、模型-视图(Model/View)模式、源-监听器(Source/Listener)模式或从属者(Dependents)模式。
观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态上发生变化时,会通知所有观察者对象,使它们能够自动更新自己。
15、观察者模式(Observer)
包括这个模式在内的接下来的四个模式,都是类和类之间的关系,不涉及到继承,学的时候应该 记得归纳,记得本文最开始的那个图。观察者模式很好理解,类似于邮件订阅和RSS订阅,当我们浏览一些博客或wiki时,经常会看到RSS图标,就这的意思是,当你订阅了该文章,如果后续有更新,会及时通知你。其实,简单来讲就一句话:当一个对象变化时,其它依赖该对象的对象都会收到通知,并且随着变化!对象之间是一种一对多的关系。先来看看关系图:
我解释下这些类的作用:MySubject类就是我们的主对象,Observer1和Observer2是依赖于MySubject的对象,当MySubject变化时,Observer1和Observer2必然变化。AbstractSubject类中定义着需要监控的对象列表,可以对其进行修改:增加或删除被监控对象,且当MySubject变化时,负责通知在列表内存在的对象。我们看实现代码:
一个Observer接口:
两个实现类:
Subject接口及实现类:
测试类:
输出:
update self!
observer1 has received! observer2 has received!这些东西,其实不难,只是有些抽象,不太容易整体理解,建议读者:根据关系图,新建项目,自己写代码(或者参考我的代码),按照总体思路走一遍,这样才能体会它的思想,理解起来容易!
1)问题描述:编写一个气象站、一个工人or学生两个类;当气象站更新添加的时候,要通知人做出相应的处理;
实现方法:通过事件监听方式的实现
2)类结构:
广播类:WeatherStation
听众类:Emp && Student
订阅天气预报的接口:Weather
测试类:WeatherMain
3)代码
WeatherStation.java
package com.dp.ood;import java.util.ArrayList;import java.util.Random;/*** * 观察者模式:事件监听 * @author admin * 需求:编写一个气象站、一个工人两个类;当气象站更新添加的时候, * 要通知人做出相应的处理 * * 问题1:不能 出现 气象站更新了多次天气,然后人才做一次的处理 * * 问题2:不能 气象站只能够通知一个人 * * 问题3:不能 只是服务于一种群体 * * 观察者设计模式的步骤: * 1.当目前对象发生指定动作时,要通知另外一个对象作出相应的处理, * 这时候应该把对方的相应处理方法定义在接口上; * 2.在当前对象维护的接口的引用,当当前对象发生指定的动作时即可调用接口中的方法 * */public class WeatherStation { String[] weathers={"Sun","Flog","Wind","Snow"}; //Current weather String currentWeather; //人 /*Emp e; public WeatherStation(Emp e){ this.e=e; }*/ ArrayListWeather.javalist=new ArrayList (); public void addListener(Weather e){ list.add(e); } //Start public void startWork() throws InterruptedException{ Random random=new Random(); new Thread(){ @Override public void run(){ while(true){//Update cycle: 1-1.5s updateWeather(); //e.notifyWeather(); for(Weather e:list){ e.notifyWeather(currentWeather); } int s=random.nextInt(501)+1000; try { Thread.sleep(s); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } }.start(); } //Update weather public void updateWeather(){ Random random=new Random(); int index=random.nextInt(weathers.length); currentWeather=weathers[index]; System.out.println("Current weather: "+currentWeather); } }
package com.dp.ood;//订阅天气预报的接口public interface Weather { void notifyWeather(String weather);}
Emp.java
package com.dp.ood;//人根据天气做出相应的处理public class Emp implements Weather{ String name; public Emp(String name) { super(); this.name = name; } //weathers={"Sun","Flog","Wind","Snow"}; public void notifyWeather(String weather){ if(weather.equals("Sun")){ System.out.println(name+"go for job Sunny."); }else if(weather.equals("Snow")){ System.out.println(name+"go for job snowly."); }else{ System.out.println(name+"go for job others."); } }}Student.java
package com.dp.ood;public class Student implements Weather{ String name; public Student(String name) { super(); this.name = name; } //weathers={"Sun","Flog","Wind","Snow"}; public void notifyWeather(String weather){ if(weather.equals("Sun")){ System.out.println(name+"go to school Sunny."); }else if(weather.equals("Snow")){ System.out.println(name+"go to school snowly."); }else{ System.out.println(name+"go to school others."); } }}WeatherMain.java
package com.dp.ood;public class WeatherMain { public static void main(String[] args) throws InterruptedException { //工人 Emp e=new Emp("Daniel"); Emp e2=new Emp("Lili"); Student s1=new Student("Ergou"); Student s2=new Student("Sanya"); WeatherStation station=new WeatherStation(); station.addListener(e); station.addListener(e2); station.addListener(s1); station.addListener(s2); station.startWork(); }}4)测试结果
Current weather: SnowDanielgo for job snowly.Liligo for job snowly.Ergougo to school snowly.Sanyago to school snowly.Current weather: FlogDanielgo for job others.Liligo for job others.Ergougo to school others.Sanyago to school others.Current weather: SnowDanielgo for job snowly.Liligo for job snowly.Ergougo to school snowly.Sanyago to school snowly.Current weather: SnowDanielgo for job snowly.Liligo for job snowly.Ergougo to school snowly.Sanyago to school snowly.Current weather: SnowDanielgo for job snowly.Liligo for job snowly.Ergougo to school snowly.Sanyago to school snowly.