设计模式笔记之观察者模式(Observer Patterns)

来源:互联网 发布:html js图片轮播 编辑:程序博客网 时间:2024/05/16 01:56
一、概述:

有一个气象站,对外提供气象服务,不同的手机应用程序来购买或退订该服务,怎样合理有效的管理这些应用程序及气象服务?

二、分析:

定义一个接口,对外提供服务,并提供退订及定制服务的方法,当有数据更新时通知所有订制该服务的Observer,
定义多个观察者,可订制或退订服务

三、实现:

1创建一个主题接口:

public interface Subject { /**  * 提供注册服务  * @param observer  */ public void registerObserver(Observer observer); /**  * 提供退订服务  * @param observer  */ public void removeObserver(Observer observer); /**  * 通知所有的Observer  */ public void notifyObserver();}

2.实现该接口,对外提供具体的服务:

public class WeatherData implements Subject {  private int low;              //最低气温  private int height;             //最高气温  private String weather;            //天气情况  //用来存放所有订制了该服务的观察者  private List<Observer> observers= new ArrayList<Observer>();    /**   * 通知所有观察者   */  @Override  public void notifyObserver() {     for(Observer o : observers){       o.update(getLow(), getHeight(), getWeather());     }  }    /**   * 订制该服务   * @param o 观察者,订制该服务的对象都是观察者   */  @Override  public void registerObserver(Observer o) {     if(o == null)       throw new NullPointerException();     if(!observers.contains(o)){       observers.add(o);     }  }  /**   * 取消订制   */  @Override  public void removeObserver(Observer observer) {     if(observer == null)       throw new NullPointerException();     if(observers.contains(observer)){       observers.remove(observer);     }  }  /**   * 气象数据更新了,通知所有观察者   * @param low   * @param height   * @param weather   */  public void setData(int low,int height,String weather){     this.low = low;     this.height = height;     this.weather = weather;     notifyObserver();  }//getters() and setters()}

3.定义观察者接口:
public interface Observer { //更新信息 public void update(int low,int height,String weather);}
4.创建观察者,可创建多个:

public class IPhone implements Observer/**  * 创建该对象时就订制服务  * @param s  */ public IPhone(Subject s){  s.registerObserver(this); } @Override public void update(int low, int height, String weather) {  System.out.println("IPhone:\tlow:" + low + "\theight:" + height + "\tweather:"+weather); } 

5.测试:

WeatherData w  = new WeatherData();  new Andriod(w);  new IPhone(w);  w.setData(20, 34, "bit");

6.运行结果:

所有的订制了该服务的观察者都通知到了:
Andriod: low:20 height:34 weather:bit
IPhone: low:20 height:34 weather:bit

当然观察者还可以取消该服务,则有信息更新后就不会通知该观察者了
四、JDK内置的观察者模式:

1.创建实现提供服务的类:

public class WeatherData extends java.util.Observable private int low;      //最低气温 private int height;      //最高气温 private String weather;     //天气情况  //气象数据更新了,通知所有观察者 public void setData(int low,int height,String weather){  this.low = low;  this.height = height;  this.weather = weather;  changed(); } //通知所有观察者 private void changed() {  setChanged();  notifyObservers(); }

2.创建观察者:

public class Andriod implements java.util.Observer//订制服务 public Andriod(Observable o){  o.addObserver(this); } //接收数据 @Override public void update(Observable o, Object arg) {  if(o instanceof WeatherData){   WeatherData w = (WeatherData) o;   this.low = w.getLow();   this.height = w.getHeight();   this.weather = w.getWeather();   display();  }  } //退订服务 public void exit(Observable o){  if(o instanceof Observable){   WeatherData w = (WeatherData) o;   w.deleteObserver(this);  }  } //接收到数据后执行操作 private void display() {  System.out.println("Andriod:\tlow:" + low + "\theight:" + height + "\tweather:"+weather); }
3。测试:

WeatherData  w = new WeatherData();  new IPhone(w);  Andriod a = new Andriod(w);  a.exit(w);   //退订  w.setData(20, 34, "good");
观察者模式解决了多个客户订制服务于退订服务的问题,该模式定义了对象乊间一对多的关系  ,主题用一个共同的接口来更新观察者 
主题和观察者之间用松耦合的方式结合,主题不知道观察者的细节,只知道观察者实现了观察者接口
 


原创粉丝点击