觀察者模式中,一個被觀察者管理所有相依於它的觀察者物件,並且在本身的狀態改變時主動發出通知。這通常通過呼叫各觀察者所提供的方法來實現。此種模式通常被用來實現事件處理系統。
角色
抽象被觀察者角色:把所有對觀察者對象的引用保存在一個集合中,每個被觀察者角色都可以有任意數量的觀察者。被觀察者提供一個接口,可以增加和刪除觀察者角色。一般用一個抽象類和接口來實現。
抽象觀察者角色:爲所有具體的觀察者定義一個接口,在得到主題的通知時更新自己。
具體被觀察者角色:在被觀察者內部狀態改變時,給所有登記過的觀察者發出通知。具體被觀察者角色通常用一個子類實現。
具體觀察者角色:該角色實現抽象觀察者角色所要求的更新接口,以便使本身的狀態與主題的狀態相協調。通常用一個子類實現。如果需要,具體觀察者角色可以保存一個指向具體主題角色的引用。
適用場景
1) 當一個抽象模型有兩個方面, 其中一個方面依賴於另一方面。將這二者封裝在獨立的對象中以使它們可以各自獨立地改變和複用。
2) 當對一個對象的改變需要同時改變其它對象, 而不知道具體有多少對象有待改變。
3) 當一個對象必須通知其它對象,而它又不能假定其它對象是誰。換言之, 你不希望這些對象是緊密耦合的。
應用:通過一個簡單的例子,描述學生給玩遊戲和看電影的學生把風,如果看見老師來了,則通知玩遊戲和看電影的學生老師來了,該學習了,老師沒看見玩遊戲和看電影的學生做小動作。如果沒看見老師,則玩遊戲和看電影的學生被老師看到。
下面是源碼:
1 Observer 抽象的觀察者
package com.whf.observer;
/*
* @author:辰
* @E-mail:[email protected]
* @2017年6月19日下午5:44:38
*/
/**
* 抽象的觀察者
* @author WU
*
*/
public interface Observer {
/**
* 更新接口狀態
* @param state
*/
public void update(String state);
}
2 Watched 抽象的被觀察者
package com.whf.observer;
/*
* @author:辰
* @E-mail:[email protected]
* @2017年6月19日下午5:45:39
*/
/**
* 抽象的 【被觀察者】
* 聲明的方法(添加、移除觀察者,通知觀察者)
* @author WU
*
*/
public interface Watched {
public void addWatcher(Observer observer);
public void removeWatcher(Observer observer);
public void notifyWatchers();
}
3 PlayGameStudent類
package com.whf.observer;
/*
* @author:辰
* @E-mail:[email protected]
* @2017年6月19日下午5:50:05
*/
/**
* 具體的觀察者
* 玩遊戲的學生
* @author WU
*
*/
public class PlayGameStudent implements Observer {
@Override
public void update(String state) {
// TODO Auto-generated method stub
System.out.println("玩遊戲的學生,老師來了,"+state);
}
}
4 WactchMoveStudent 類
package com.whf.observer;
/*
* @author:辰
* @E-mail:[email protected]
* @2017年6月19日下午5:50:05
*/
/**
* 具體的觀察者
* 看電影的學生
* @author WU
*
*/
public class WactchMoveStudent implements Observer {
@Override
public void update(String state) {
// TODO Auto-generated method stub
System.out.println("看電影的學生,老師來了,"+state);
}
}
5 Sutdent 類
package com.whf.observer;
import java.util.ArrayList;
/*
* @author:辰
* @E-mail:[email protected]
* @2017年6月19日下午5:47:27
*/
/**
* 具體的觀察者
* @author WU
*
*/
public class Student implements Watched{
/**
* 用來保存註冊的觀察者對象
*/
private ArrayList<Observer> observe = new ArrayList<Observer>();
private String state;
public Student(String state) {
super();
this.state = state;
}
public void setState(String state) {
this.state = state;
this.notifyWatchers();
}
/**
* 註冊觀察者對象
* 觀察者對象
*/
@Override
public void addWatcher(Observer observer) {
// TODO Auto-generated method stub
observe.add(observer);
}
/**
* 刪除觀察者對象
* 觀察者對象
*/
@Override
public void removeWatcher(Observer observer) {
// TODO Auto-generated method stub
observe.remove(observer);
}
/**
* 通知所有註冊的觀察者對象
*/
@Override
public void notifyWatchers() {
// TODO Auto-generated method stub
for(Observer observer : observe){
observer.update(state);
}
}
}
6 Teacher 類
package com.whf.observer;
import java.util.ArrayList;
import java.util.List;
/*
* @author:辰
* @E-mail:[email protected]
* @2017年6月19日下午6:52:45
*/
/**
* 具體的被觀察者
* @author WU
*
*/
public class Teacher implements Watched{
/**
* 用來保存註冊的觀察者對象
*/
private List<Observer> list = new ArrayList<Observer>();
/**
* 狀態
*/
private String state;
public Teacher(String state) {
super();
this.state = state;
}
public void setState(String state) {
this.state = state;
this.notifyWatchers();
}
/**
* 註冊觀察者對象
* 觀察者對象
*/
@Override
public void addWatcher(Observer observer) {
// TODO Auto-generated method stub
list.add(observer);
}
/**
* 刪除觀察者對象
* 觀察者對象
*/
@Override
public void removeWatcher(Observer observer) {
// TODO Auto-generated method stub
list.remove(observer);
}
/**
* 通知所有註冊的觀察者對象
*/
public void notifyWatchers() {
// TODO Auto-generated method stub
for(Observer observer : list){
observer.update(state);
}
}
}
7 Client 類
package com.whf.observer;
/*
* @author:辰
* @E-mail:[email protected]
* @2017年6月19日下午7:33:58
*/
/**
* 客戶端測試類
* @author WU
*
*/
public class Client {
public static void main(String[] args) {
//被觀察的學生
Student student = new Student("");
//被觀察的老師
Teacher teacher = new Teacher("");
//玩遊戲的學生
PlayGameStudent playGameStudent = new PlayGameStudent();
//看電影的學生
WactchMoveStudent wactchMoveStudent = new WactchMoveStudent();
// 註冊觀察者對象
student.addWatcher(playGameStudent);
student.addWatcher(wactchMoveStudent);
// 註冊觀察者對象
teacher.addWatcher(playGameStudent);
teacher.addWatcher(wactchMoveStudent);
//情況一 : 學生看見老師,狀態發生變化
System.out.println("--------學生看見老師來了----------");
student.setState("學生看見老師來了,並進行提醒,老師沒看見 ^_^");
System.out.println("\n");
//情況二 : 學生未老師,狀態發生變化
System.out.println("---------學生沒看見老師來了-------");
teacher.setState("學生沒看見老師,老師看見了");
}
}
測試結果:
--------學生看見老師來了----------
玩遊戲的學生,老師來了,學生看見老師來了,並進行提醒,老師沒看見 ^_^
看電影的學生,老師來了,學生看見老師來了,並進行提醒,老師沒看見 ^_^
---------學生沒看見老師來了-------
玩遊戲的學生,老師來了,學生沒看見老師,老師看見了
看電影的學生,老師來了,學生沒看見老師,老師看見了
至此,一個簡單的觀察者模式實現。