一、概述:
2.实现该接口,对外提供具体的服务:
3.定义观察者接口:
5.测试:
6.运行结果:
2.创建观察者:
主题和观察者之间用松耦合的方式结合,主题不知道观察者的细节,只知道观察者实现了观察者接口
有一个气象站,对外提供气象服务,不同的手机应用程序来购买或退订该服务,怎样合理有效的管理这些应用程序及气象服务?
二、分析:
定义一个接口,对外提供服务,并提供退订及定制服务的方法,当有数据更新时通知所有订制该服务的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");
观察者模式解决了多个客户订制服务于退订服务的问题,该模式定义了对象乊间一对多的关系 ,主题用一个共同的接口来更新观察者
主题和观察者之间用松耦合的方式结合,主题不知道观察者的细节,只知道观察者实现了观察者接口