設計模式之觀察者模式(釋出/訂閱模式:publish/subscribe)
定義了一種一對多的依賴關係,讓多個觀察者物件同時監聽某一個主題物件.這個主題物件在狀態發生變化時,會通知所有觀察者物件,使它們能夠自動更新自己
觀察者模式的關鍵物件是主題Subject和觀察者Observer.一個Subject可以有任意數目依賴它的Observer,
一旦Subject的狀態發生了改變,所有的Observer都可以得到通知.Subject發出通知的時候並不需要知道誰是它的Observer.
而且任何具體的觀察者也不知道其他觀察者是什麼
觀察者模式的使用場景
當一個物件的改變需要同時改變其他物件,並且不需要知道具體多少需要改變
Subject類,可翻譯為主題或抽象通知者,一般用一個抽象類或者一個介面實現.它把所有對觀察者物件的引用儲存在一個聚集裡,每個主題都可以有任何數量的觀察者.
抽象主題提供一個介面,可以增加和刪除觀察者物件.
Observer類,抽象觀察者,為所有的具體觀察者定義一個介面,在得到主題的通知時更新自己.這個介面叫做更新介面.抽象觀察者一般用一個抽象類或者一個介面實現.
更新介面通常包含一個Update()方法,這個方法叫做更新方法.
ConcreteSubject類,叫做具體主題或具體通知者,將有關狀態存入具體觀察者物件;在具體主題的內部狀態改變時,給所有登記過的觀察者發出通知.
具體主題角色通常用一個具體子類實現
public static void main(String[] args) {
SubscriptionSubject mSubscriptionSubject=new SubscriptionSubject();
//建立微信使用者
WeixinUser user1=new WeixinUser("a");
WeixinUser user2=new WeixinUser("b");
WeixinUser user3=new WeixinUser("c");
//訂閱公眾號
mSubscriptionSubject.add(user1);
mSubscriptionSubject.add(user2);
mSubscriptionSubject.add(user3);
mSubscriptionSubject.notify("d的專欄更新了");
}
/**
* 微信使用者是觀察者,微信公眾號是被觀察者,有多個的微信使用者關注了一個公眾號
* 當這個公眾號更新時就會通知這些訂閱的微信使用者
*抽象觀察類
* @author guk
*
*/
public interface Observer {
public void update(String message);
}
/**
* 具體觀察者 ConcreteObserver
* @author guk
*
*/
public class WeixinUser implements Observer {
//微信使用者名稱
private String name;
public WeixinUser(String name) {
super();
this.name = name;
}
@Override
public void update(String message) {
System.out.println(name+"-"+message);
}
}
/**
* 抽象被觀察者類Subject
* @author guk
*
*/
public interface Subject {
/**
* 增加訂閱者
* @param observer
*/
void add(Observer observer);
/**
* 刪除訂閱者
* @param observer
*/
void delete(Observer observer);
/**
* 通知訂閱者更新訊息
* @param message
*/
void notify(String message);
}
/**
* 具體被觀察者(ConcreteSubject)
* @author guk
*
*/
public class SubscriptionSubject implements Subject {
//儲存訂閱公眾號的微信使用者
private List<Observer> weixinUserList=new ArrayList<Observer>();
@Override
public void add(Observer observer) {
weixinUserList.add(observer);
}
@Override
public void delete(Observer observer) {
weixinUserList.remove(observer);
}
@Override
public void notify(String message) {
for(Observer observer:weixinUserList) {
observer.update(message);
}
}
}