寶可夢社收購印刷廠力求供貨平穩 寶可夢卡黃牛黨慌了
觀察者模式是眾多軟體設計模式中的一種,又稱釋出訂閱模式.被觀察的物件發生了變化,觀察者物件們可以第一時間收到通知, 並作出相應的處理,例如作為一家餐館的會員,若餐館出了新品那麼會第一時間通知到各個會員,不是會員的路人則不會收到通知
再看一下類圖:
FoodSubject sub = new FoodSubject(); new LisaObserver(sub); Observer tom = new TomObserver(sub); System.out.println("----菜品釋出------"); Thread.sleep(1000); sub.onChange("剁椒魚頭", "80.00", "熱菜"); System.out.println("--- tom竟然取消關注 ---"); sub.remove(tom); System.out.println("----又有菜品釋出哦------"); Thread.sleep(1000); sub.onChange("外婆菜炒蛋", "18.00", "熱菜");
----菜品釋出------
我是lisa, 食物:剁椒魚頭,價格:80.00,菜品型別:熱菜
我是tom, 食物:剁椒魚頭,價格:80.00,菜品型別:熱菜
--- tom竟然取消關注 ---
----又有菜品釋出哦------
我是lisa, 食物:外婆菜炒蛋,價格:18.00,菜品型別:熱菜
JDK已經幫我們實現了觀察者模式,Observable相當於Subject,Observer同上自定義的Observer,只有一個方法: //①.被觀察者物件,②.引數 void update(Observable o, Object arg);
Observable是一個class而非一個介面 提供addObserver(Observer o) deleteObserver(Observer o)
notifyObservers() notifyObservers(Object arg) //必須在呼叫notifyObservers方法前先呼叫一次 //因為只有為true時才會通知觀察者 void setChanged()
public class News extends Observable{ private String subject; private String content; private Date date; public News() {} public void onChange(String subject, String content){ this.subject = subject; this.content = content; this.date = new Date(); setChanged(); notifyObservers(); } public String getSubject() { return subject; } public String getContent() { return content; } public Date getDate() { return date; } }
public class Person implements Observer, IShow {
private News news;
private String name;
public Person(Observable subject, String name) {
subject.addObserver(this);
this.name = name;
}
@Override
public void update(Observable o, Object arg) {
if (o == null || !(o instanceof News)) {
return;
}
news = (News) o;
show();
}
@Override
public void show() {
System.out.println("我是" + name + ",我閱讀了:n 主題:" + news.getSubject() + "n內容:"
+ news.getContent()
+ "n釋出時間:" + news.getDate());
}
如果觀察者物件不需要所有的引數
public class Lisa implements Observer, IShow{
private News news;
public Lisa(Observable subject) {
subject.addObserver(this);
}
@Override
public void show() {
System.out.println("我是lisa,我閱讀了最新的新聞:n 主題:" + news.getSubject() + ",內容:"
+ news.getContent());
}
@Override
public void update(Observable o, Object arg) {
if(o == null || !(o instanceof News)){
return;
}
news = (News)o;
show();
}
public interface IShow {
void show();
}
//測試
News news = new News();
System.out.println("----- 新聞資訊 -------");
String subject = "生態養海 擁海而興";
String content = "進入11月下旬,海風吹在臉上已有些刺骨,但溫州洞頭區東屏街道東嶴村,漁家樂的生意依舊紅火。";
new Tom(news);
new Person(news,"any");
new Person(news,"tony");
new Person(news,"lexa");
Lisa lisa = new Lisa(news);
news.onChange(subject, content);
Thread.sleep(1000);
System.out.println("lisa不感興趣,取消關住.");
news.deleteObserver(lisa);
Thread.sleep(1000);
System.out.println("----- 又釋出了最新資訊 --------");
subject = "特朗普赦免感恩節火雞:它將擁有一個非常光明的未來";
content = "美國總統特朗普21日遵照白宮的節日傳統,在感恩節前赦免了兩隻火雞。";
news.onChange(subject, content);
----- 新聞資訊 -------
我是lisa,我閱讀了最新的新聞:
主題:生態養海 擁海而興,內容:進入11月下旬,海風吹在臉上已有些刺骨,但溫州洞頭區東屏街道東嶴村,漁家樂的生意依舊紅火。
我是lexa,我閱讀了:
主題:生態養海 擁海而興
內容:進入11月下旬,海風吹在臉上已有些刺骨,但溫州洞頭區東屏街道東嶴村,漁家樂的生意依舊紅火。
釋出時間:Thu Nov 23 16:53:16 CST 2017
我是tony,我閱讀了:
主題:生態養海 擁海而興
內容:進入11月下旬,海風吹在臉上已有些刺骨,但溫州洞頭區東屏街道東嶴村,漁家樂的生意依舊紅火。
釋出時間:Thu Nov 23 16:53:16 CST 2017
我是any,我閱讀了:
主題:生態養海 擁海而興
內容:進入11月下旬,海風吹在臉上已有些刺骨,但溫州洞頭區東屏街道東嶴村,漁家樂的生意依舊紅火。
釋出時間:Thu Nov 23 16:53:16 CST 2017
我是tom,我閱讀了:
主題:生態養海 擁海而興,內容:進入11月下旬,海風吹在臉上已有些刺骨,但溫州洞頭區東屏街道東嶴村,漁家樂的生意依舊紅火。,釋出時間:Thu Nov 23 16:53:16 CST 2017
lisa不感興趣,取消關住.
----- 又釋出了最新資訊 --------
我是lexa,我閱讀了:
主題:特朗普赦免感恩節火雞:它將擁有一個非常光明的未來
內容:美國總統特朗普21日遵照白宮的節日傳統,在感恩節前赦免了兩隻火雞。
釋出時間:Thu Nov 23 16:53:18 CST 2017
我是tony,我閱讀了:
主題:特朗普赦免感恩節火雞:它將擁有一個非常光明的未來
內容:美國總統特朗普21日遵照白宮的節日傳統,在感恩節前赦免了兩隻火雞。
釋出時間:Thu Nov 23 16:53:18 CST 2017
我是any,我閱讀了:
主題:特朗普赦免感恩節火雞:它將擁有一個非常光明的未來
內容:美國總統特朗普21日遵照白宮的節日傳統,在感恩節前赦免了兩隻火雞。
釋出時間:Thu Nov 23 16:53:18 CST 2017
我是tom,我閱讀了:
主題:特朗普赦免感恩節火雞:它將擁有一個非常光明的未來,內容:美國總統特朗普21日遵照白宮的節日傳統,在感恩節前赦免了兩隻火雞。,釋出時間:Thu Nov 23 16:53:18 CST 2017
因為Observable是一個“類”,你必須設計一個類繼承它。如果某類想同時 具有Observable類和另一個超類的行為,就會陷入兩難,畢竟Java不支援多重繼承。 這限制了Observable的複用潛力. 再者,因為沒有Observable介面,所以無法建立自己的實現和Java內建的 Observer搭配使用,也無法將java.util的實現換成另一套做法的實現(比方說, 如果你能夠擴充套件java.util.Observable,那麼Observable“可能”可以符合你的需求。 否則,你可能需要像本章開頭的做法那樣自己實現這一整套觀察者模式。 而且setChanged()方法被保護起來了(被定義成protected)。這意味著:除非你繼承自Observable,否則你無法建立Observable例項並組合到你自己的物件中來。