对象间一对多的依赖关系,当一个对象对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。
举例:假设有三个人,小美,小王和小李。小美很漂亮,小王和小李都喜欢小美,时刻关注小美的一举一动,有一天,小美说了一句:“谁来陪我打游戏”。这句话被小王和小李听到了,结果乐坏了,就邀请小美一起玩游戏。
在这里,小美就是被观察者,小王和小李就是观察者,被观察者发出一条信息,然后观察者进行相应的处理。
public interface Person {
void getMessage(String message);
}
public class XiaoWang implements Person {
private String name = "小王";
@Override
public void getMessage(String message) {
System.out.println(name + "接到了小美打过来的电话,电话内容是:" + message);
}
}
public class XiaoLi implements Person {
private String name = "小李";
@Override
public void getMessage(String message) {
System.out.println(name + "接到了小美打过来的电话,电话内容是:" + message);
}
}
public class XiaoMei {
List<Person> list = new ArrayList<>();
public XiaoMei() {
}
public void addPerson(Person person) {
list.add(person);
}
// 遍历list,把自己的通知发送给所有暗恋自己的人
public void notifyPerson() {
for(Person person : list) {
person.getMessage("你们过来吧,一起玩游戏");
}
}
}
public class Test {
public static void main(String[] args) {
XiaoMei xiaoMei = new XiaoMei();
XiaoWang xiaoWang = new XiaoWang();
XiaoLi xiaoLi = new XiaoLi();
// 小王和小李在小美哪里都注册了一下
xiaoMei.addPerson(xiaoWang);
xiaoMei.addPerson(xiaoLi);
// 小美向小王和小李发送通知
xiaoMei.notifyPerson();
}
}
实际应用场景
- 业务处理之后的文本日志
- 业务处理之后的数据库日志
- 业务处理后发送短信、邮件等
传统解决方案及弊端
存在问题
一旦某个业务逻辑发生变化,如购票业务增加其他业务逻辑,休要修改购票核心文件、甚至购票流程。
日记月累后,文件冗长,导致后续维护困难。
存在问题的主要原因是程序的紧密耦合。使用观察者模式将目前的业务逻辑优化成松耦合。达到易维护、易修改的目的。同时也辐射面向接口编程的思想。
观察者模式典型实现方式
- 定义两个接口: 观察者(通知)接口、被观察者(主题)接口
- 定义两个类:观察者对象实现观察者接口,被观察者类实现被观察者接口
- 被观察者类注册自己需要通知的观察者对象
- 被观察者某个业务逻辑发生时通知观察者对象,每个观察者对象执行自己的业务逻辑