觀察者模式在線版:訂閱-發布模型的在線示范
一直以來對觀察者模式(Observer)一直理解為訂閱發布模式,這樣或許更好理解一些。現實中的博客RSS定制(在谷歌pubsubhubbub未出現以前,客戶端都是被動的拉數據,PULL模式),需要客戶端主動定時輪詢方可。谷歌PUBSUBHUBBUB協議的問世,是一個創新,RSS主動推送的協議,非常實時,發布-訂閱的最好典型。
觀察者模式的詳細定義以及相關理論,可以參見《設計模式》,里面講的很透徹。
本文將帶來一個在線版本的訂閱-發布,用戶添加一篇博文,所有訂閱者可以馬上得到通知,主動推送方式,避免了系統的大量無謂請求。雖有點PUBSUBHUBBUB協議的味道,但離實踐還缺少很多,是一個演示。
這個演示模擬的場景是關心特定博主的所有訂閱者可以在新的博文發表之后的瞬間得到通知。從博文的發布到通知所有的訂閱者知曉,可以以毫秒計算(比較理想的情況下,諸如服務器性能強勁,網絡好,算法不錯等)。但這里的訂閱者是有限制的,必須要有一個可以被內容發布者服務器回調的URL地址,否則將不能實時通知到訂閱者。這里強調的是可以被內容發布者服務器訪問。演示模擬的場景在一個機器上多個站點之間進行,同一個局域網其它或者聯網的環境下在理論上也都是可以的。
需要先添加訂閱者:
若退訂,步驟相同,致死要選擇“退訂”即可。
這個表單可以放在其它訂閱者站點下面,只是FORM的URL地址要正確。
進入站點首頁即可看到所有訂閱者的回調地址:
有了訂閱者之后,需要添加博文,測試我們的訂閱者。
點擊提交按鈕之后,在各個站點終端下即可看到:
為了演示,我們定義了兩個訂閱者站點: subscribeOne和subscribeTwo,一個顯示所獲取的數據,一個把獲取的數據持久化到磁盤中。
下面看看主站點的一些代碼,首先來一個傳統意義上觀察者模式。
需要觀察的對象,即目標 BlogService.java
還需要定義了一個觀察者,接口實現:
有兩個具體的子類觀察者,一個負責把博客的數據生成靜態的文件,但這個不是重點,所以沒有具體的代碼附加;另外一個觀察者負責把新的博文通知到所有的訂閱者。
/**
/**
當前端發布了一篇博文后,會觸發這兩個觀察者。
訂閱-發布模型,較適合于一個主端節點主動向各個訂閱者節點主動推送信息,相比被動的拉模式,更為節省網絡帶寬以及服務器的性能。
在一個范圍較大的局域網之間,彼此域之間的信息實時通知,也會是一個較好的應用。
在范圍更大的互聯網環境下,一個具有相當大的數量級訂閱者的主機將可節省珍貴的機房帶寬,經濟收益不可小覷。
源代碼下載
觀察者模式的詳細定義以及相關理論,可以參見《設計模式》,里面講的很透徹。
本文將帶來一個在線版本的訂閱-發布,用戶添加一篇博文,所有訂閱者可以馬上得到通知,主動推送方式,避免了系統的大量無謂請求。雖有點PUBSUBHUBBUB協議的味道,但離實踐還缺少很多,是一個演示。
這個演示模擬的場景是關心特定博主的所有訂閱者可以在新的博文發表之后的瞬間得到通知。從博文的發布到通知所有的訂閱者知曉,可以以毫秒計算(比較理想的情況下,諸如服務器性能強勁,網絡好,算法不錯等)。但這里的訂閱者是有限制的,必須要有一個可以被內容發布者服務器回調的URL地址,否則將不能實時通知到訂閱者。這里強調的是可以被內容發布者服務器訪問。演示模擬的場景在一個機器上多個站點之間進行,同一個局域網其它或者聯網的環境下在理論上也都是可以的。
需要先添加訂閱者:

若退訂,步驟相同,致死要選擇“退訂”即可。

這個表單可以放在其它訂閱者站點下面,只是FORM的URL地址要正確。
進入站點首頁即可看到所有訂閱者的回調地址:

有了訂閱者之后,需要添加博文,測試我們的訂閱者。

點擊提交按鈕之后,在各個站點終端下即可看到:

為了演示,我們定義了兩個訂閱者站點: subscribeOne和subscribeTwo,一個顯示所獲取的數據,一個把獲取的數據持久化到磁盤中。
下面看看主站點的一些代碼,首先來一個傳統意義上觀察者模式。
需要觀察的對象,即目標 BlogService.java
/**
* 博文操作
* @author yongboy@gmail.com
* @date 2010-10-18
* @version 1.0
*/
public class BlogService {
private static Set<BlogObserver> obserserList;
static {
obserserList = new HashSet<BlogObserver>();
}
public void addBlog(Blog blog) {
System.out.println("保存博文一些操作......");
// 忽略具體邏輯
System.out.println("執行通知到所有的訂閱者....");
updateObsersers(blog);
}
private void updateObsersers(Blog blog) {
for (BlogObserver server : obserserList) {
server.update(blog);
}
}
public void addObserver(BlogObserver blogObserver) {
obserserList.add(blogObserver);
}
public void removeObserver(BlogObserver blogObserver) {
obserserList.remove(blogObserver);
}
public void clearObserver() {
obserserList.clear();
}
}
可以看到內含觀察者的一些簡單的管理操作。
public interface BlogObserver {
void update(Blog blog);
}
有兩個具體的子類觀察者,一個負責把博客的數據生成靜態的文件,但這個不是重點,所以沒有具體的代碼附加;另外一個觀察者負責把新的博文通知到所有的訂閱者。
/**
* 為新建的博文生成靜態頁面
*
* @author yongboy@gmail.com
* @date 2010-10-19
* @version 1.0
*/
public class BlogGenPageObserver implements BlogObserver {
public void update(Blog blog) {
// 具體生成代碼省略
System.out.println("博文靜態頁面觀察者開始工作......");
}
}
/**
* 定義一個博客信息推送觀察者
* @author yongboy@gmail.com
* @date 2010-10-18
* @version 1.0
*/
public class BlogNotifyObserver implements BlogObserver {
public void update(Blog blog) {
System.out.println("博文推送觀察者開始工作......");
// 生成單篇博客的RSS
RssService rssService = new RssService(blog);
String rssContent = rssService.ouputRss();
// 通知訂閱者,分發博客內容
NotifyService notifyService = new NotifyService(rssContent);
notifyService.doNotice();
}
}
當前端發布了一篇博文后,會觸發這兩個觀察者。
訂閱-發布模型,較適合于一個主端節點主動向各個訂閱者節點主動推送信息,相比被動的拉模式,更為節省網絡帶寬以及服務器的性能。
在一個范圍較大的局域網之間,彼此域之間的信息實時通知,也會是一個較好的應用。
在范圍更大的互聯網環境下,一個具有相當大的數量級訂閱者的主機將可節省珍貴的機房帶寬,經濟收益不可小覷。
源代碼下載
posted on 2010-10-19 10:14 nieyong 閱讀(1687) 評論(1) 編輯 收藏 所屬分類: Java