设计模式 - 观察者模式

思考

  • 观察者模式是什么?如何类比?描述观察者模式的工作过程?
  • Subject 的作用是什么?Observer 的作用是什么?
  • 观察者模式中当数据更新后如何通知给用户

概念

  • 观察者模式:
    • 该模式通过两个类实现订阅-通知服务,SubjectOberver
    • Subject:表示负责登记,通知,移除的类,比如气象局和用气象数据的用户,气象局负责注册使用数据的用户,当数据更新及时通知给用户
      • 换句话就是说,Subject该类负责管理用户类队列,当数据更新时,可以调用被管理的用户类里的方法(实现所谓的及时通知)
    • Observer:使用数据的类
    • 举例:邮局和用户,气象局和用户

实现代码

通用类图



//接口, 让WeatherData 来实现 
public interface Subject {
	
	public void registerObserver(Observer o);
	public void removeObserver(Observer o);
	public void notifyObservers();
}



import java.util.ArrayList;

/**
 * 类是核心
 * 1. 包含最新的天气情况信息 
 * 2. 含有 观察者集合,使用ArrayList管理
 * 3. 当数据有更新时,就主动的调用   ArrayList, 通知所有的(接入方)就看到最新的信息
 * @author Administrator
 *
 */
public class WeatherData implements Subject {
	private float temperatrue;
	private float pressure;
	private float humidity;
	//观察者集合
	private ArrayList<Observer> observers;
	
	//加入新的第三方

	public WeatherData() {
		observers = new ArrayList<Observer>();
	}

	public float getTemperature() {
		return temperatrue;
	}

	public float getPressure() {
		return pressure;
	}

	public float getHumidity() {
		return humidity;
	}

	public void dataChange() {
		//调用 接入方的 update
		
		notifyObservers();
	}

	//当数据有更新时,就调用 setData
	public void setData(float temperature, float pressure, float humidity) {
		this.temperatrue = temperature;
		this.pressure = pressure;
		this.humidity = humidity;
		//调用dataChange, 将最新的信息 推送给 接入方 currentConditions
		dataChange();
	}

	//注册一个观察者
	@Override
	public void registerObserver(Observer o) {
		// TODO Auto-generated method stub
		observers.add(o);
	}

	//移除一个观察者
	@Override
	public void removeObserver(Observer o) {
		// TODO Auto-generated method stub
		if(observers.contains(o)) {
			observers.remove(o);
		}
	}

	//遍历所有的观察者,并通知
	@Override
	public void notifyObservers() {
		// TODO Auto-generated method stub
		for(int i = 0; i < observers.size(); i++) {
			observers.get(i).update(this.temperatrue, this.pressure, this.humidity);
		}
	}
}



  
//观察者接口,有观察者来实现  
public interface Observer {  
  
    public void update(float temperature, float pressure, float humidity);  
}



public class CurrentConditions implements Observer {

	// 温度,气压,湿度
	private float temperature;
	private float pressure;
	private float humidity;

	// 更新 天气情况,是由 WeatherData 来调用,我使用推送模式
	public void update(float temperature, float pressure, float humidity) {
		this.temperature = temperature;
		this.pressure = pressure;
		this.humidity = humidity;
		display();
	}

	// 显示
	public void display() {
		System.out.println("***Today mTemperature: " + temperature + "***");
		System.out.println("***Today mPressure: " + pressure + "***");
		System.out.println("***Today mHumidity: " + humidity + "***");
	}
}


  
public class Client {  
  
    public static void main(String[] args) {  
       // TODO Auto-generated method stub  
       //创建一个WeatherData  
       WeatherData weatherData = new WeatherData();  
         
       //创建观察者  
       CurrentConditions currentConditions = new CurrentConditions();  
       BaiduSite baiduSite = new BaiduSite();  
         
       //注册到weatherData  
       weatherData.registerObserver(currentConditions);  
       weatherData.registerObserver(baiduSite);  
         
       //测试  
       System.out.println("通知各个注册的观察者, 看看信息");  
       weatherData.setData(10f, 100f, 30.3f);  
         
         
       weatherData.removeObserver(currentConditions);  
       //测试  
       System.out.println();  
       System.out.println("通知各个注册的观察者, 看看信息");  
       weatherData.setData(10f, 100f, 30.3f);  
    }  
  
}


Prev Post 设计模式 - 设计原则 - 单一职责原则
Next Post 设计模式 - 适配器模式1 - 包装器模式 - 类适配器模式