1. 程式人生 > 遊戲 >寶可夢社收購印刷廠力求供貨平穩 寶可夢卡黃牛黨慌了

寶可夢社收購印刷廠力求供貨平穩 寶可夢卡黃牛黨慌了

觀察者模式是眾多軟體設計模式中的一種,又稱釋出訂閱模式.被觀察的物件發生了變化,觀察者物件們可以第一時間收到通知, 並作出相應的處理,例如作為一家餐館的會員,若餐館出了新品那麼會第一時間通知到各個會員,不是會員的路人則不會收到通知

再看一下類圖:

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例項並組合到你自己的物件中來。