精心整理了设计模式——观察者模式,并配图加代码,方便理解,实属不易,但是难免不了存在纰漏,感谢大家的指正与理解!觉的写的不错的小伙伴儿,一键三连支持一下,后期会有持续更新!!抱拳了罒ω罒
观察者模式简介
-
观察者模式(Observer),又叫发布-订阅模式(Publish/Subscribe),定义对象间一种 一对多 的依赖关系,使得每当一个对象改变状态,则所有依赖于它的对象都会得到通知并自动更新。
-
观察者模式的主要角色:
- 抽象主题(Subject):它是一个抽象类或接口,主要包括保存观察者的集合,增加、删除、通知观察者对象的方法。
- 具体主题(Concrete Subject):也叫具体目标类,它是抽象主题的具体实现。
- 抽象观察者(Observer):它是一个抽象类或接口,一个更新自己的方法,当接到具体主题的更改通知时被调用。
- 具体观察者(Concrete Observer):抽象观察者的具体实现。
-
例子
- 猫叫了一声,吓着了老鼠,也惊到了主人,猫是被观察者(主题),老鼠和人是观察者
- 同事都在玩游戏,前台小姐姐通知了一声老板来了,同事立马更新自己的状态(由 “摸鱼” 变为写代码),前台小姐姐是被观察者,员工是观察者。
-
具体的结构图
具体主题会增加删除具体的观察者,并且会向具体观察者发出更新通知;当具体观察者收到通知者(具体主题)的更新通知时及时更新。
观察者模式的实现
下面举一个具体实例,假设百度和新浪的网站的天气预报都是调用气象局的网站的接口,每当天气有变化时,气象局就会及时通知百度和新浪的网站,使其及时更改网站的天气预报。
Subject接口:抽象主题接口,也就是通知者接口,增加、删除、通知百度和新浪等观察者。
interface Subject{
//增加观察者
public void addObs(Observer o);
//删除观察者
public void deleteObs(Observer o);
//通知观察者
public void notifyObs();
}
Observer接口:抽象观察者接口。
interface Observer{
//更改的天气的状态
public void update(String status);
}
WeatherData 类:具体主题,具体的通知者,代表气象局的网站
class WeatherData implements Subject{
//代表的天气的状态
private String status;
//存放观察者的集合
List<Observer>list = new ArrayList<>();
public void setStatus(String status) {
this.status = status;
}
@Override
public void addObs(Observer o) {
list.add(o);
}
@Override
public void deleteObs(Observer o) {
list.remove(o);
}
//通知每一个观察者更新数据
@Override
public void notifyObs() {
for ( Observer o : list) {
o.update(status);
}
}
}
BaiDu 类和Sina 类:代表具体的观察者,表示百度和新浪的网站的天气预报
class BaiDu implements Observer{
@Override
public void update(String status) {
System.out.println("百度天气状态为:"+status);
}
}
class Sina implements Observer{
@Override
public void update(String status) {
System.out.println("新浪天气状态为:"+status);
}
}
演示:
public class ObserverTest {
public static void main(String[] args) {
//气象局的天气状态为大风天气
WeatherData wd = new WeatherData();
wd.setStatus("大风");
//百度和新浪的网站
BaiDu bd = new BaiDu();
Sina sa = new Sina();
//通知百度和新浪的网站,更新天气的数据
wd.addObs(bd);
wd.addObs(sa);
wd.notifyObs();
System.out.println("==========================");
//表示天气变为下大雨状态
wd.setStatus("下大雨");
//但是没有通知百度进行天气的更新
wd.deleteObs(bd);
wd.notifyObs();
//输出
//百度天气状态为:大风
//新浪天气状态为:大风
//==========================
//新浪天气状态为:下大雨
}
}
总结
- 观察者模式是一种对象行为型模式,其主要优点如下:
1) 降低了目标与观察者之间的耦合关系,两者之间是抽象耦合关系。符合依赖倒置原则。
2) 目标与观察者之间建立了一套触发机制。- 它的主要缺点如下:
1) 目标与观察者之间的依赖关系并没有完全解除,而且有可能出现循环引用。
2) 当观察者对象很多时,通知的发布会花费很多时间,影响程序的效率。
参考文章:
https://www.cnblogs.com/adamjwh/p/10913660.html
http://c.biancheng.net/view/1390.html