第十八章:观察者模式
一、模式简介
观察者模式有两个组成部分:观察者(Observer)和 被观察者(Subject)
Subject 就像一个内容创作者,Observer 如果订阅了它,Subject 内部就将这个 Observer 保存在内部一个集合中。Subject 可以有很多 Observer,一旦 Subject 创作的内容更新,就可以调用每个 Observer 自己的更新方法将新创作的内容推送给每个 Observer
二、模式实例
现在我们有一个 up 主,他有很多订阅者,每次发一个新视频他需要推送给每个订阅他的用户
Subject 接口
public interface Subject {
void registerObserver(Observer observer);
void removeObserver();
void notifyObserver();
}
Observer 接口
public interface Observer {
void display(Video video);
}
创作者类(Subject)
public class Creator implements Subject {
List<Observer> observers;
List<Video> videos;
private int position;
public Creator() {
this.observers = new ArrayList<>(8);
this.videos = new ArrayList<>(8);
position = -1;
}
public void createVideo(String name, String category) {
Video video = new Video(name, category);
this.videos.add(video);
position++;
}
@Override
public void registerObserver(Observer observer) {
observers.add(observer);
}
@Override
public void removeObserver() {
observers.remove(observers);
}
@Override
public void notifyObserver() {
observers.forEach((observer) -> observer.display(this.videos.get(position)));
}
}
订阅者类(Observer)
public class Subscriber implements Observer {
private String name;
public Subscriber(String name) {
this.name = name;
}
@Override
public void display(Video video) {
System.out.println("亲爱的" + this.name + " 新的视频更新啦!");
System.out.println(video);
}
}
内容类
public class Video {
private String name;
private String category;
public Video(String name, String category) {
this.name = name;
this.category = category;
}
@Override
public String toString() {
return "视频名称: " + this.name + " 分类: " + category;
}
}
测试类
public class ObserverTest {
public static void main(String[] args) {
Subscriber subscriber1 = new Subscriber("没有昵称");
Subscriber subscriber2 = new Subscriber("用户已注销");
Subscriber subscriber3 = new Subscriber("123");
Creator creator = new Creator();
// 注册订阅者
creator.registerObserver(subscriber1);
creator.registerObserver(subscriber2);
creator.registerObserver(subscriber3);
creator.createVideo("今日要闻", "新闻");
// 推送
creator.notifyObserver();
System.out.println("==========");
// 又有新的用户订阅
Subscriber subscriber4 = new Subscriber("张三");
creator.registerObserver(subscriber4);
creator.createVideo("震惊!!!", "新闻");
// 再次推送
creator.notifyObserver();
}
}
三、模式总结
1)Subject 内部使用集合的形式保存 Observer,所以可以很方便的增删订阅者即观察者
2)不需要 Observer 来定时轮询 Subject 有没有更新,Subject 一旦有更新就可以立即推送