—-慢慢来比较快,虚心学技术—-

概念

又称为发布-订阅者模式,定义对象间一种一对多的依赖关系,使得每当一个对象改变状态,则所有依赖它的对象都会得到通知并自动更新。

让多个观察者对象同时监听某一个主题对象。这个主题对象在状态变化时,会通知所有的观察者对象,使他们能够自动更新自己

角色:

抽象主题(Subject)**:把所有观察者保存到一个集合中,可以有任意数量观察者,抽象主题提供接口以增加和移除观察者对象。(即抽象被观察者)

具体主题(ConcreteSubject)**:实现抽象主题,当主题状态发生变化时,通知集合中所有的观察者(即具体被观察者)

抽象观察(Observer)**:为所有具体观察者定义一个统一接口,在收到主题的通知时更新自身

具体观察(ConcreteObserver)**:实现抽象观察,以便在收到主题的通知时更新自身

实例

需求**:作为明星,拥有无数粉丝,那么每次自己更新动态都会通知到每一位粉丝**

粉丝抽象类(抽象观察者):

  1. interface Fans{
  2. //获取粉丝名称
  3. String getFansName();
  4. //更新粉丝信息
  5. void update(String message);
  6. }

粉丝具体类(具体观察者):

  1. class ConcreteFans implements Fans{
  2. private String fansName;
  3. public ConcreteFans(String fansName){
  4. this.fansName = fansName;
  5. }
  6. public String getFansName(){
  7. return this.fansName;
  8. }
  9. @Override
  10. public void update(String message) {
  11. System.out.println(fansName + " 收到消息:===========" + message);
  12. }
  13. }

明星抽象类(抽象主题):

  1. interface Star {
  2. //增加粉丝
  3. void addFans(Fans fans);
  4. //移除粉丝
  5. void removeFans(Fans fans);
  6. //发布消息
  7. void post(String message);
  8. //通知粉丝
  9. void notify(String message);
  10. }

明星具体类(具体主题):

  1. class ConcreteStar implements Star{
  2. //明星名称
  3. String startName;
  4. public ConcreteStar(String startName){
  5. this.startName = startName;
  6. }
  7. /**
  8. * 粉丝列表
  9. */
  10. private List<Fans> fansList = new ArrayList<>();
  11. @Override
  12. public void addFans(Fans fans) {
  13. System.out.println("明星 "+startName+" 多了个粉丝:"+fans.getFansName());
  14. fansList.add(fans);
  15. }
  16. @Override
  17. public void removeFans(Fans fans) {
  18. System.out.println("明星 "+startName+" 移除了粉丝:"+fans.getFansName());
  19. fansList.remove(fans);
  20. }
  21. @Override
  22. public void post(String message) {
  23. message = "明星 "+startName+" 发布动态:"+message;
  24. System.out.println(message);
  25. //通知粉丝
  26. notify(message);
  27. }
  28. @Override
  29. public void notify(String message) {
  30. for (Fans fans : fansList)
  31. fans.update(message);
  32. }
  33. }

调用:

  1. Star star = new ConcreteStar("刘美眉");
  2. Fans fans1 = new ConcreteFans("虹桥一姐");
  3. Fans fans2 = new ConcreteFans("真爱粉刘一手");
  4. Fans fans3 = new ConcreteFans("黑粉史无心");
  5. //新增粉丝
  6. star.addFans(fans1);
  7. star.addFans(fans2);
  8. star.addFans(fans3);
  9. //发布消息
  10. star.post("今天很开心,我演唱会很成功!!!");

结果:每个粉丝都得到通知,明星发布了动态

  1. 明星 刘美眉 多了个粉丝:虹桥一姐
  2. 明星 刘美眉 多了个粉丝:真爱粉刘一手
  3. 明星 刘美眉 多了个粉丝:黑粉史无心
  4. 明星 刘美眉 发布动态:今天很开心,我演唱会很成功!!!
  5. 虹桥一姐 收到消息:===========明星 刘美眉 发布动态:今天很开心,我演唱会很成功!!!
  6. 真爱粉刘一手 收到消息:===========明星 刘美眉 发布动态:今天很开心,我演唱会很成功!!!
  7. 黑粉史无心 收到消息:===========明星 刘美眉 发布动态:今天很开心,我演唱会很成功!!!

应用场景

对象之间存在一对多的关系,一个对象的更改会影响其他对象。

多用于订阅功能,如微博的订阅、MQ设计,Spring事件机制等
**

优点

降低目标与观察者的耦合关系,实现抽象耦合,且两者之间建立了触发机制
**

缺点

观察者多的时候,发布消息的时间就会延长,影响程序效率。

目标与观察者并没有完全消除依赖关系,可能导致循环引用

如有贻误,还请评论指正