一.觀察者模式
在許多的設計中,經常涉及到許多對象都對一個對象的數據變化感興趣,且這多個對象都希望跟蹤這個特殊的對象的數據.
如,職介所與求職者之間的關係,報社與訂閱者之間的關係......
觀察者模式是關於多個對象想知道一個對象中數據變化情況的一種成熟模式,該模式中包含了四個角色,分別是:主題,觀
察者,具體的主題和具體的觀察者,本示例使用了觀察者模式模擬了報社與訂閱者之間的關係.
二. 觀察者模式的類圖如下:
三.完整的示例代碼如下:
1. 主題
package behavioralPattern.observer.observer1;
/**
* @ClassName: Subject
* @Description: TODO(主題接口)
* @author Liyongbin
* @date 2011-2-7 上午11:39:53
* @version V1.0
*/
public interface ISubject {
//添加一個觀察者
public void addObserver(IObserver o);
//刪除一個觀察者
public void removeObserver(IObserver o);
//通知一個觀察者
public void notifyObserver();
}
2. 觀察者
package behavioralPattern.observer.observer1;
/**
* @ClassName: Observer
* @Description: TODO(觀察者)
* @author Liyongbin
* @date 2011-2-7 上午11:46:27
* @version V1.0
*/
public interface IObserver {
/**
* 觀察的內容
* @param news 新聞
* @param lapseRate 氣溫
*/
public void update(String news,float lapseRate);
}
3. 顯示新聞和天氣信息
package behavioralPattern.observer.observer1;
/**
* @ClassName: IDisplayContent
* @Description: 顯示新聞和天氣信息
* @author Liyongbin
* @date 2011-2-7 下午04:09:24
* @version V1.0
*/
public interface IDisplayContent {
public void display();
}
4. 出版社類[具體主題]
package behavioralPattern.observer.observer1;
import java.util.ArrayList;
import java.util.List;
/**
* @ClassName: Publish
* @Description:(出版社類)
* @author Liyongbin
* @date 2011-2-7 上午11:33:23
* @version V1.0
*/
public class Publish implements ISubject {
// 用來存放訂閱者
public List<IObserver> observers = new ArrayList<IObserver>();
// 更新新聞和氣溫
public boolean changed;
// 新聞
public String news;
// 氣溫
public float lapseRate;
/**
* 構造方法
*/
public Publish() {
changed = false;
news="";
lapseRate=0.0f;
}
/**
* 添加訂閱者
*/
@Override
public void addObserver(IObserver observer) {
// 訂閱者名單中不存在該訂閱者時,將其添加進來
if (!observers.contains(observer)) {
observers.add(observer);
}
}
/**
* 通知訂閱者
*/
@Override
public void notifyObserver() {
if (changed) {
for (IObserver observer:observers) {
observer.update(news, lapseRate);
}
}
}
/**
* 刪除訂閱者
*/
@Override
public void removeObserver(IObserver observer) {
// 訂閱者名單中存在該訂閱者時,將其刪除
if (observers.contains(observer)) {
observers.remove(observer);
}
}
/**
* 更新今天的新聞
*/
public void changeCurrentMessages(String news,float lapseRate){
if (this.news.equals(news) && this.lapseRate==lapseRate) {
changed=false;
}else{
this.news=news;
this.lapseRate=lapseRate;
changed=true;
}
}
}
5.具體的觀察者--訂閱者A
package behavioralPattern.observer.observer1;
/**
* @ClassName: Subscribe_A
* @Description: TODO(訂閱者A)
* @author Liyongbin
* @date 2011-2-7 下午12:04:04
* @version V1.0
*/
public class Subscribe_A implements IObserver,IDisplayContent {
private String name;
private String news;
private float lapseRate;
public Subscribe_A() {
name="用戶: Subscribe_A";
}
//更新新聞
@Override
public void update(String news, float lapseRate) {
this.news=news;
this.lapseRate=lapseRate;
}
//顯示新聞
@Override
public void display() {
System.out.println(name);
System.out.println("今天的新聞是:"+news);
System.out.println("今天的氣溫是:"+lapseRate+"度");
}
}
具體的觀察者--訂閱者B
package behavioralPattern.observer.observer1;
/**
* @ClassName: Subscribe_B
* @Description: TODO(訂閱者A)
* @author Liyongbin
* @date 2011-2-7 下午12:04:04
* @version V1.0
*/
public class Subscribe_B implements IObserver,IDisplayContent {
private String name;
private String news;
private float lapseRate;
public Subscribe_B() {
name="用戶: Subscribe_B";
}
//更新新聞
@Override
public void update(String news, float lapseRate) {
this.news=news;
this.lapseRate=lapseRate;
}
//顯示新聞
@Override
public void display() {
System.out.println(name);
System.out.println("今天的新聞是:"+news);
System.out.println("今天的氣溫是:"+lapseRate+"度");
}
}
具體的觀察者--訂閱者C
package behavioralPattern.observer.observer1;
/**
* @ClassName: Subscribe_C
* @Description: TODO(訂閱者C)
* @author Liyongbin
* @date 2011-2-7 下午12:04:04
* @version V1.0
*/
public class Subscribe_C implements IObserver,IDisplayContent {
private String name;
private String news;
private float lapseRate;
public Subscribe_C() {
name="用戶: Subscribe_C";
}
//更新新聞
@Override
public void update(String news, float lapseRate) {
this.news=news;
this.lapseRate=lapseRate;
}
//顯示新聞
@Override
public void display() {
System.out.println(name);
System.out.println("今天的新聞是:"+news);
System.out.println("今天的氣溫是:"+lapseRate+"度");
}
}
6.測試代碼如下:
package behavioralPattern.observer.observer1;
/**
* @ClassName: ObserverTest
* @Description: 測試觀察者模式
* @author Liyongbin
* @date 2011-2-7 下午12:05:52
* @version V1.0
*/
public class ObserverTest {
public static void main(String[] args) {
Publish publish = new Publish();
Subscribe_A sa = new Subscribe_A();
Subscribe_B sb = new Subscribe_B();
Subscribe_C sc = new Subscribe_C();
//更新新聞
publish.changeCurrentMessages("經濟新聞", 23.4f);
//添加訂閱者
publish.addObserver(sa);
publish.addObserver(sb);
publish.addObserver(sc);
//通知訂閱者
publish.notifyObserver();
System.out.println("---------------------");
sa.display();
sb.display();
sc.display();
//用戶B 退出訂閱
publish.removeObserver(sb);
//更新新聞
publish.changeCurrentMessages("體育新聞", 15.7f);
//通知訂閱者
publish.notifyObserver();
System.out.println("---------------------");
sa.display();
sb.display();
sc.display();
}
}
7. 運行結果如下: