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

一、概述:

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

二、分析:

定义一个接口,对外提供服务,并提供退订及定制服务的方法,当有数据更新时通知所有订制该服务的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");
观察者模式解决了多个客户订制服务于退订服务的问题,该模式定义了对象乊间一对多的关系  ,主题用一个共同的接口来更新观察者 
主题和观察者之间用松耦合的方式结合,主题不知道观察者的细节,只知道观察者实现了观察者接口
 


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值