观察者模式

分享视频链接:https://www.bilibili.com/video/BV1PC4y1x7ig/

 

以下是文字稿和幻灯片:

大家好,我今天给大家分享的是观察者模式:

在生活中我们有一个很常见的场景,也就是在等红绿灯的时候

这里面呢,观察者就是我们的汽车,而观察目标就是我们的交通信号灯。

他们之间是一个一对多的关系,建立一种对象与对象之间的依赖关系,一个对象发生改变时将自动通知其他对象,其他对象将相应做出反应

那我们来看看是什么是观察者模式:

观察者模式(Observer Design Pattern)也被称为发布订阅模式(Publish-Subscribe Design Pattern)

在对象之间定义一个一对多的依赖,当一个对象状态改变的时候,所有依赖的对象都会自动收到通知。

Define a one-to-many dependency between objects so that when one object changes state, all its dependents are notified and updated automatically.

观察者模式 UML类图:

模式包含4个角色:

Subject: 目标

ConcreteSubject:具体目标

Observer: 观察者

ConcreteObserver: 具体观察者

我们下面来看一下代码实践:

一个天气预报系统,凡是订阅了改天气预报的,当天气发生改变的时候就把通知发送给所有订阅该天气预报的人。如兽人族(Orcs)和霍比特人(Hobitts)订阅了该天气预报系统,当天气从晴变成雨天的时候,兽人族和霍比特人就收到了天气变成雨天的通知。 如果还有其他订阅了该天气预报的如人族(Terran),只需要在WeatherObserver中加入该人族(Terran)订阅者,这样当天气发生改变的时候,人族也会收到天气通知。

 

  1 //先定义天气类型(WeatherType.java),定义为枚举类型(sunny,rainny,windy,clod)
  2 public enum WeatherType {
  3     SUNNY,WINDY,CLOD,RAINY;
  4 
  5     @Override
  6     public String toString(){
  7         return this.name().toLowerCase();
  8     }
  9 }
 10 
 11 //再将订阅者抽象成一个接口(WeatherObserver.java),所有订阅天气预报系统的必须实现这个接口
 12 public interface WeatherObserver {
 13       public void Upadate(WeatherType currentWeather);
 14 }
 15 
 16 //天气类(Weather)负责定义数据结构来接收订阅者和通知更新订阅者天气变化。使用List<WeatherObserver>来接收订阅者,定义方法addObserver来接收新的订阅者和notifyAllObsever方法来更新订阅者天气状态。
 17 import java.util.ArrayList;
 18 import java.util.List;
 19 
 20 public class Weather {
 21      private WeatherType currentWeather;
 22      private List<WeatherObserver> observers;
 23      
 24      public Weather(){
 25          observers=new ArrayList<>();
 26          currentWeather=WeatherType.SUNNY;
 27      }
 28      
 29      public void addObservers(WeatherObserver observer){
 30          observers.add(observer);
 31      }
 32      
 33      public void removeObservers(WeatherObserver observer){
 34          observers.remove(observer);
 35      }
 36      
 37      
 38      public  void timePasses(){
 39          WeatherType[] enumValues=WeatherType.values();
 40         /* for(WeatherType type:enumValues){
 41              System.out.println(type);
 42          }*/
 43          //改变天气,让天气的enum类型往后推一个
 44          currentWeather=enumValues[(currentWeather.ordinal() + 1) % enumValues.length];
 45          System.out.println("The weather change to  "+currentWeather);
 46          notifyAllObserver();
 47      }
 48      
 49      public void notifyAllObserver(){
 50          for(WeatherObserver obs: observers){
 51              obs.Upadate(currentWeather);
 52          }
 53      }
 54 }
 55 
 56 //添加两个订阅天气预报的“人”,一个兽族(Orcs.java)一个霍比特人(Hobitts.java)。 如上面所说,要订阅该天气预报必须实现WeatherOberver接口。
 57 public class Orcs implements WeatherObserver{
 58 
 59     @Override
 60     public void Upadate(WeatherType currentWeather) {
 61         switch(currentWeather){
 62         case CLOD:
 63             System.out.println("The orcs are freezing cold");
 64             break;
 65         case SUNNY:
 66             System.out.println("The sun hurts the orcs' eyes.");
 67             break;
 68         case RAINY:
 69             System.out.println("The orcs are dripping wet.");
 70             break;
 71         case WINDY:
 72             System.out.println("The orc smell almost vanishes in the wind.");
 73         default:
 74             break;
 75         }        
 76     }
 77 
 78 
 79 public class Hobbits implements WeatherObserver{
 80 
 81     @Override
 82     public void Upadate(WeatherType currentWeather) {
 83         switch(currentWeather){
 84         case CLOD:
 85             System.out.println("The Hobbits are freezing cold");
 86             break;
 87         case SUNNY:
 88             System.out.println("The sun hurts the Hobbits' eyes.");
 89             break;
 90         case RAINY:
 91             System.out.println("The Hobbits are dripping wet.");
 92             break;
 93         case WINDY:
 94             System.out.println("The Hobbits smell almost vanishes in the wind.");
 95         default:
 96             break;
 97         }       
 98     }
 99 }
100 
101 //测试
102 public class APP {
103     public static void main(String[] args){
104         Weather weather=new Weather();
105         weather.addObservers(new Orcs());
106         weather.addObservers(new Hobbits());
107         
108         //weather.addObservers(new Terran());
109         
110         weather.timePasses();
111         
112         //weather.timePasses();
113         
114     }
115 }

观察者模式可以实现表示层和数据逻辑层的分离。

观察者模式在观察目标和观察者之间建立一个抽象的耦合。

观察者模式支持广播通信。

将所有的观察者都通知到会花费很多时间可能存在循环依赖

谢谢大家

 

posted @ 2020-04-15 20:19  王柯  阅读(283)  评论(0编辑  收藏  举报