觀察者模式
在對象之間定義了一對多的依賴,這樣一來,當一個對象改變狀態,依賴它的對象會收到通知並自動更新
觀察模式中的參與者
- 抽象主題(Subject):它把所有觀察者對象的引用保存到一個劇集裏,每個主題都可以有任意數量的觀察者。抽象主題提供一個接口,可以增加和刪除觀察者對象,以及通知所有觀察者
- 具體主題(ConcreteSubject):將有關狀態存入具體觀察者對象;當具體主題內部狀態發生改變時,通知所有註冊過的觀察者
- 抽象觀察者(Observer):爲所有的具體觀察者定義一個接口,在得到主題通知時更新自己
- 具體觀察者(ConcreteObserver):實現抽象觀察者角色所要求的更新接口,以便使本身的狀態與主題狀態保持一致
實現示例
有一個公衆號服務,不定時發佈一些消息,關注公衆號就可以收到推送消息,取消關注就收不到推送消息。
抽象主題 (添加、刪除、通知觀察者的方法)
package observer;
public interface Subject {
void registerObserver(Observer observer);
void removeObserver(Observer observer);
void notifyObserver(String message);
}
抽象觀察者
package observer;
public interface Observer {
void update(String message);
}
公衆號服務
package observer;
import java.util.ArrayList;
import java.util.List;
public class WechatServer implements Subject {
private List<Observer> observers = new ArrayList<>();
@Override
public void registerObserver(Observer observer) {
observers.add(observer);
}
@Override
public void removeObserver(Observer observer) {
if (!observers.isEmpty()) {
observers.remove(observer);
}
}
@Override
public void notifyObserver(String message) {
for (Observer observer : observers) {
observer.update(message);
}
}
public void setInfomation(String s) {
System.out.println("微信服務更新消息:" + s);
//消息更新通知所有觀察者
notifyObserver(s);
}
}
用戶
package observer;
public class User implements Observer {
private String name;
public User(String name) {
this.name = name;
}
@Override
public void update(String message) {
read(message);
}
public void read(String message) {
System.out.println(name + "收到推送消息:" + message);
}
}
測試
package observer;
import org.junit.Test;
public class ObserverTest {
@Test
public void test(){
User user = new User("lara");
User user1 = new User("yolada");
User user2 = new User("wendy");
WechatServer wechatServer = new WechatServer();
wechatServer.registerObserver(user);
wechatServer.registerObserver(user1);
wechatServer.registerObserver(user2);
wechatServer.setInfomation("雙十一馬上到了");
wechatServer.removeObserver(user);
wechatServer.setInfomation("雙十一已經結束了");
}
}
測試結果
微信服務更新消息:雙十一馬上到了
lara收到推送消息:雙十一馬上到了
yolada收到推送消息:雙十一馬上到了
wendy收到推送消息:雙十一馬上到了
微信服務更新消息:雙十一已經結束了
yolada收到推送消息:雙十一已經結束了
wendy收到推送消息:雙十一已經結束了