观察者模式



1. 观察者模式(Observer Pattern)

指多个对象间存在一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新,它是对象行为型模式。主题(Subject)具有注册和移除观察者、并通知所有观察者的功能,主题是通过维护一张观察者列表来实现这些操作的。


顾名思义,观察者模式需要观察者和被观察者(主题),所以其主要组成对象有:

  • Subject(主题抽象类)

  • ConcreteSubject(主题实现类)

  • Observer(观察者抽象类)

  • ConcreteSubject(观察者实现类)



2. 流程

模拟一个场景:多个天气数据公告板会在天气信息发生改变时更新其内容


主题抽象类

public interface Subject {
	
    // 注册
    void resisterObserver(Observer o);

    // 移除
    void removeObserver(Observer o);

    // 通知
    void notifyObserver();
}

主题实现类

public class WeatherSubject implements Subject {

	// 维护的观察者列表
	private List<Observer> observers = new ArrayList<Observer>();
	
	// 主题的状态
    private float temperature;
    private float humidity;
    private float pressure;

	@Override
	public void resisterObserver(Observer observer) {
		observers.add(observer);
	}

	@Override
	public void removeObserver(Observer observer) {
		observers.remove(observer);
	}

	@Override
	// 就是这里通知的
	public void notifyObserver() {
		for(Observer value : observers){
			value.update(temperature, humidity, pressure);
		}
	}
	
	// 状态改变
	public void setMeasurements(float temperature, float humidity, float pressure) {
		this.temperature = temperature;
        this.humidity = humidity;
        this.pressure = pressure;
        notifyObserver();
	}
}

观察者抽象类

public abstract class Observer {
	
	public abstract void update(float temp, float humidity, float pressure);

}

观察者实现类

public class DisplayOne extends Observer {

	@Override
	public void update(float temp, float humidity, float pressure) {
		System.out.println("公告板1收到状态变更:" + temp + " " + humidity + " " + pressure);
	}
}
public class DisplayTwo extends Observer {

	@Override
	public void update(float temp, float humidity, float pressure) {
		System.out.println("公告板2收到状态变更:" + temp + " " + humidity + " " + pressure);
	}
}

测试

public class test {

	public static void main(String[] args) {
		
		Observer one = new DisplayOne();
		Observer two = new DisplayTwo();
		
		WeatherSubject subject = new WeatherSubject();
		subject.resisterObserver(one);
		subject.resisterObserver(two);
		
		// 天气变化
		System.out.println("天气变化了-----");
		subject.setMeasurements(100, 100, 100);
	}
}
天气变化了-----
公告板1收到状态变更:100.0 100.0 100.0
公告板2收到状态变更:100.0 100.0 100.0


https://www.pdai.tech/md/dev-spec/pattern/19_observer.html