观察者设计模式:时当一个对象发生指定的动做时,要经过另外的对象作出相应的处理。设计模式
步骤:
1. A对象发生指定的动做是,要通知B,C,D...对象作出相应的处理,这时候应该把B,C,D...对象针对A对象的动做作出的相应处理方法定义在接口上(这是一种规范,凡事须要A对象通知的对象,都要实现该接口)。
2. 在A对象维护接口的引用,当A对象发生指定的动做这时候便可调用接口中的方法。dom
观察者模式的应用场景:ide
1. 对一个对象状态的更新,须要其余对象同步更新,并且其余对象的数量动态可变。this
2.对象仅须要将本身的更新通知给其余对象而不须要知道其余对象的细节。spa
假设有一个例子:设计
气象台天天都会更新天气预报,订阅的人群均可以在每次气象台发布天气预报,均可以接收到天气预报信息.订阅人群能够根据天气预报信息作出相应处理code
被观察对象(Subject)server
1 /* 2 * 气象台类 3 * 4 */ 5 public class WeatherStation { 6 7 private String[] weatherArr = {"大雨","大雪","台风","雾霾","多云","晴"}; 8 private String weatherDesc = weatherArr[0]; 9 private ArrayList<IWeather> list = new ArrayList<IWeather>(); 10 11 //对外提供一个方法添加天气预报更新时,要通知的对象 12 public void add(IWeather weather){ 13 this.list.add(weather); 14 } 15 16 //对外提供一个方法取消订阅天气预报 17 public void remove(IWeather weather){ 18 if(weatherArr.length>0){ 19 for (int i = 0; i < weatherArr.length; i++) { 20 if(list.get(i).equals(weather)){ 21 this.list.remove(i); 22 break; 23 } 24 } 25 26 } 27 } 28 29 30 //开始天气预报 31 public void startWeatherForecast(){ 32 new Thread(){ 33 @Override 34 public void run() { 35 while(true){ 36 updateWeather();//每3秒钟更新一次天气预报 (模拟天天气象台自动更新天气预报) 37 for (IWeather weather : list) { 38 weather.updateWeather(weatherDesc); 39 } 40 try { 41 Thread.sleep(3000); 42 } catch (InterruptedException e) { 43 e.printStackTrace(); 44 } 45 46 } 47 } 48 }.start(); 49 50 } 51 52 53 //气象台更新天气 54 public void updateWeather(){ 55 Random random = new Random(); 56 int n = random.nextInt(weatherArr.length); 57 this.weatherDesc = weatherArr[n]; 58 System.out.println("气象台发布天气预报:"+this.weatherDesc); 59 } 60 61 }
全部订阅的群体必须具备一个共同updateWeather的方法(实现该接口),这样气象台发布新天气预报时候,便可经过调用订阅对象执行该方法,达到通知目的。对象
/* * 一个接口规范,实现了该接口对象所要作的动做。 * 实现该接口的对象当气象台天气预报更新时执行 * {"大雨","大雪","台风","雾霾","多云","晴"} */ public interface IWeather { public void updateWeather(String weatherDesc); }
订阅的群体类 观察者对象Observerblog
1 /* 2 * 可能订阅群个之一,工做者 3 * 4 */ 5 public class Emp implements IWeather { 6 7 String name; 8 int age; 9 10 public Emp(String name, int age) { 11 this.name = name; 12 this.age = age; 13 } 14 15 //{"大雨","大雪","台风","雾霾","多云","晴"} 16 @Override 17 public void updateWeather(String weatherDesc) { 18 System.out.println(this.name+":收到天气预报 "+weatherDesc); 19 } 20 }
-
/* * 可能订阅群体之一, 学生 */ public class Student implements IWeather { String name; int age; public Student(String name, int age) { this.name = name; this.age = age; } //{"大雨","大雪","台风","雾霾","多云","晴"} @Override public void updateWeather(String weatherDesc) { System.out.println(this.name+":收到天气预报 "+weatherDesc); } }
Main、
1 public class WeatherMain { 2 3 public static void main(String[] args) { 4 WeatherStation weatherStation = new WeatherStation(); 5 6 Student s1 = new Student("小明", 10); 7 Student s2 = new Student("小美", 10); 8 Emp e1 = new Emp("大明", 10); 9 Emp e2 = new Emp("大美", 10); 10 weatherStation.add(s1); 11 weatherStation.add(s2); 12 weatherStation.add(e1); 13 weatherStation.add(e2); 14 weatherStation.remove(e2); 15 weatherStation.startWeatherForecast(); 16 } 17 18 }
由于“大美”取消了天气预报,因此没有收到天气预报通知
执行结果:
气象台发布天气预报:大雪
小明:收到天气预报 大雪
小美:收到天气预报 大雪
大明:收到天气预报 大雪
气象台发布天气预报:雾霾
小明:收到天气预报 雾霾
小美:收到天气预报 雾霾
大明:收到天气预报 雾霾
气象台发布天气预报:台风
小明:收到天气预报 台风
小美:收到天气预报 台风
大明:收到天气预报 台风
气象台发布天气预报:晴
小明:收到天气预报 晴
小美:收到天气预报 晴
大明:收到天气预报 晴
气象台发布天气预报:雾霾
小明:收到天气预报 雾霾
小美:收到天气预报 雾霾
大明:收到天气预报 雾霾
...