观察者模式又名发布-订阅(Publish/Subscribe)模式,它定义了对象的一对多关系,当对象的状态的发生改变时,所有依赖它的对象都会接到通知并自动更新。
观察模式分为四个模式
- 抽象主题
它把所有对观察者对象的引用保存到一个集合中,一个抽象主题可以对应多个观察者。
- 抽象观察者
为所有具体观察者定义的一个接口或者是类,在得到主题通知时,自动更新其子类。
- 具体主题
实现了抽象主题的类,当具体主题状态发生改变时,会通知所有注册过的观察者。
- 具体观察者
实现了抽象观察者的类,在得到具体主题的通知时,自动更新自己。
使用场景
我们订阅了某个公众号的时候,它会时不时的给我推送一些相关的信息,如果我们取消关注,那么它将不会推送信息给我们,下面通过一个简单的例子来实现观察者模式
定义抽象主题和抽象观察者
/**
* 抽象主题
*/
public interface Watched {
public void registerObserver(Watch watch);
public void removeObserver(Watch watch);
public void noticeObserver();
}
/**
* 抽象观察者
*/
public interface Watch {
public void update(Object o);
}
定义具体主题
public class ConcreteWatched implements Watched{
//定义一个list集合,用于存放具体观察者
private List<Watch> list=new ArrayList<>();
private String content;
public ConcreteWatched(String content) {
this.content = content;
}
@Override
public void registerObserver(Watch watch) {
if (!list.contains(watch)){
list.add(watch);
}
}
@Override
public void removeObserver(Watch watch) {
if (list.contains(watch)){
list.remove(watch);
}
}
@Override
public void noticeObserver() {
for (Watch watch :list) {
watch.update(content);
}
}
}
定义具体观察者
public class ConcreteWatch implements Watch{
@Override
public void update(Object o) {
System.out.println("收到的推送信息内容为:"+o);
}
}
定义测试类
public class ObserverTest {
public static void main(String[] args) {
//定义一个主题
Watched watched=new ConcreteWatched("JAVA面试宝典");
//创建两个观察者对象
Watch watch1=new ConcreteWatch();
Watch watch2=new ConcreteWatch();
//注册这两个观察者
watched.registerObserver(watch1);
watched.registerObserver(watch2);
//如果有一天watch1对这个推送信息没有兴趣了,取消了关注,那么就不会有推送信息
//watched.removeObserver(watch1);
//通知观察者
watched.noticeObserver();
}
}
上面抽象主题和抽象观察者都是自己定义的,实际开发中可直接使用jdk自带的Observable(被观察者)和Observer(观察者)。只要继承这两个类即可,然后根据自己的业务进行扩展。