观察者模式
在对象之间定义了一对多的依赖,这样一来,当一个对象改变状态,依赖它的对象会收到通知并自动更新
观察模式中的参与者
- 抽象主题(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收到推送消息:双十一已经结束了