轉自: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.javapackage 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.