对象间一对多的依赖关系,当一个对象对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。

举例:假设有三个人,小美,小王和小李。小美很漂亮,小王和小李都喜欢小美,时刻关注小美的一举一动,有一天,小美说了一句:“谁来陪我打游戏”。这句话被小王和小李听到了,结果乐坏了,就邀请小美一起玩游戏。

在这里,小美就是被观察者,小王和小李就是观察者,被观察者发出一条信息,然后观察者进行相应的处理。

  1. public interface Person {
  2. void getMessage(String message);
  3. }
  4. public class XiaoWang implements Person {
  5. private String name = "小王";
  6. @Override
  7. public void getMessage(String message) {
  8. System.out.println(name + "接到了小美打过来的电话,电话内容是:" + message);
  9. }
  10. }
  11. public class XiaoLi implements Person {
  12. private String name = "小李";
  13. @Override
  14. public void getMessage(String message) {
  15. System.out.println(name + "接到了小美打过来的电话,电话内容是:" + message);
  16. }
  17. }
  18. public class XiaoMei {
  19. List<Person> list = new ArrayList<>();
  20. public XiaoMei() {
  21. }
  22. public void addPerson(Person person) {
  23. list.add(person);
  24. }
  25. // 遍历list,把自己的通知发送给所有暗恋自己的人
  26. public void notifyPerson() {
  27. for(Person person : list) {
  28. person.getMessage("你们过来吧,一起玩游戏");
  29. }
  30. }
  31. }
  32. public class Test {
  33. public static void main(String[] args) {
  34. XiaoMei xiaoMei = new XiaoMei();
  35. XiaoWang xiaoWang = new XiaoWang();
  36. XiaoLi xiaoLi = new XiaoLi();
  37. // 小王和小李在小美哪里都注册了一下
  38. xiaoMei.addPerson(xiaoWang);
  39. xiaoMei.addPerson(xiaoLi);
  40. // 小美向小王和小李发送通知
  41. xiaoMei.notifyPerson();
  42. }
  43. }

实际应用场景

  • 业务处理之后的文本日志
  • 业务处理之后的数据库日志
  • 业务处理后发送短信、邮件等

传统解决方案及弊端

在业务逻辑代码类的内部增加相关代码,完成各种逻辑。

存在问题

一旦某个业务逻辑发生变化,如购票业务增加其他业务逻辑,休要修改购票核心文件、甚至购票流程。
日记月累后,文件冗长,导致后续维护困难。

存在问题的主要原因是程序的紧密耦合。使用观察者模式将目前的业务逻辑优化成松耦合。达到易维护、易修改的目的。同时也辐射面向接口编程的思想。

观察者模式典型实现方式

  • 定义两个接口: 观察者(通知)接口、被观察者(主题)接口
  • 定义两个类:观察者对象实现观察者接口,被观察者类实现被观察者接口
  • 被观察者类注册自己需要通知的观察者对象
  • 被观察者某个业务逻辑发生时通知观察者对象,每个观察者对象执行自己的业务逻辑