转自:http://www.cnblogs.com/shamgod/p/4588557.html
一、概述
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://blog.csdn.net/zhangerqing/article/details/8243942
典型应用:事件监听器
转自: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;
}*/
ArrayList<Weather> list=new ArrayList<Weather>();
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);
}
}
Weather.java
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: Snow
Danielgo for job snowly.
Liligo for job snowly.
Ergougo to school snowly.
Sanyago to school snowly.
Current weather: Flog
Danielgo for job others.
Liligo for job others.
Ergougo to school others.
Sanyago to school others.
Current weather: Snow
Danielgo for job snowly.
Liligo for job snowly.
Ergougo to school snowly.
Sanyago to school snowly.
Current weather: Snow
Danielgo for job snowly.
Liligo for job snowly.
Ergougo to school snowly.
Sanyago to school snowly.
Current weather: Snow
Danielgo for job snowly.
Liligo for job snowly.
Ergougo to school snowly.
Sanyago to school snowly.