我下面簡要概括一下觀察者模式的思想要點:
1、需要被觀察者,第一可以釋出通知,第二可以觸發觀察者的回調方法
2、需要觀察者,提供回調方法供被觀察者觸發
用微信公衆号的邏輯簡單說明:
使用者關注微信公衆号,使用者就是觀察者,微信公衆号就是被觀察者,微信公衆号得知道有多少使用者關注了它(得儲存起來),當微信公衆号釋出文章時(釋出通知),通知關注它的使用者(觸發觀察者的回調方法)。
下面看看簡單代碼實作以上邏輯:
觀察者接口:
package com.nobt.observer;
/**
- 定義一個觀察者接口,隻提供了更新方法,當被觀察者觸發更新方法時,會觸發被觀察者儲存的所有觀察者update();
- @author nobt
- @date 2018年12月25日 下午8:30:26
*/
public interface Observer {
public void update(String message);
}
被觀察者接口:
- 被觀察者接口,聲明添加、移除、通知觀察者
- @date 2018年12月25日 下午8:33:34
public interface Observerable {
public void addObserver(Observer o);
public void removeObserver(Observer o);
public void notifyObserver();
觀察者接口的實作類,就是公衆号例子中的使用者:
- 模拟使用者,實作觀察者接口
- @date 2018年12月25日 下午8:40:06
public class User implements Observer {
private String userName;
public User(String userName) {
super();
this.userName = userName;
}
@Override
public void update(String message) {
System.out.println(userName + " 收到推送消息: " + message);
}
被觀察者接口的實作類,就是公衆号例子中的公衆号:
import java.util.ArrayList;
import java.util.List;
- 模拟微信公衆号,實作被觀察者接口
- @date 2018年12月25日 下午8:35:28
public class Wechat implements Observerable {
//被觀察者儲存所有觀察者的集合
private List<Observer> observerList;
private String message;
public Wechat() {
observerList = new ArrayList<Observer>();
}
@Override
public void addObserver(Observer o) {
observerList.add(o);
}
@Override
public void removeObserver(Observer o) {
if(!observerList.isEmpty()){
observerList.remove(o);
}
}
@Override
public void notifyObserver() {
for(Observer o : observerList){
o.update(message);
}
}
public void topicMsg(String message) {
this.message = message;
System.out.println("微信公衆号釋出文章: " + message);
//釋出文章,通知所有觀察者
notifyObserver();
}
簡單測試類,模拟3個使用者關注公衆号,第一次釋出消息3個使用者得到通知,第二次讓其中一個使用者取消關注,将隻有兩個使用者得到通知:
- 測試類
- @date 2018年12月25日 下午8:41:42
public class TestObserver {
public static void main(String[] args) {
Wechat wc = new Wechat();
User u1 = new User("user1");
User u2 = new User("user2");
User u3 = new User("user3");
wc.addObserver(u1);
wc.addObserver(u2);
wc.addObserver(u3);
wc.topicMsg("我釋出了一篇公衆号文章:《java觀察者模式Demo》");
System.out.println("使用者user1取消了訂閱...");
wc.removeObserver(u1);
wc.topicMsg("my name is nobt...");
}
列印結果如下:
以上源碼:observer_demo: java觀察者模式demo