本文主要向大家介绍了JAVA语言观察者模式适用场景和手动实现,通过具体的内容向大家展示,希望对大家学习JAVA语言有所帮助。
定义:对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。
一、适用场景
1.当一个抽象模型有两个方面,其中一个方面依赖于另一方面。将这二者封装在独立的对象中以使它们可以各自独立地改变和复用。
2.当对一个对象的改变需要同时改变其它对象,而不知道具体有多少对象有待改变。
3.当一个对象必须通知其它对象, 而它又不能假定其它对象是谁。
二、涉及对象
1.主题接口(Subject):目标知道它的观察者。 可以有任意多个观察者观察同一个目标。提供注册和删除观察者对象的接口。
2.观察者接口(Observer):为那些在主题发生改变时需获得通知的对象定义一个更新接口
3.具体主题(ConcretSubject):将有关状态存入各ConcreteObserver 对象。当它的状态发生改变时,向它的各个观察者发出通知。
4.具体观察者(ConcretObserver):维护一个指向ConcreteSubject 对象的引用。存储有关状态, 这些状态应与目标的状态保持一致。实现 Observer 的更新接口使自身状态与目标的状态保持一致。
例子一:手动实现观察者模式
Subject类:
public interface Subject {
//注册观察者 public void
//删除观察者 public void
removeObserver(Observer o);
//当主题状态改变时,调用该方法,通知所有的观察者
public void notifyObservers(); }
Observer类:
public interface Observer {
public void update(float temp,float humidity,float pressure); }
需求的额外接口DisplayElement:
public interface DisplayElement {
public void display();
}
具体主题类–WeatherData
import java.util.ArrayList;
public class WeatherData implements Subject{
private ArrayList observers;//记录观察者
private float temperture;
private float humidity;
private float pressure;
public WeatherData() {
//在构造器中建立观察者
observers = new ArrayList();
}
@Override
public void registerObserver(Observer o) {
observers.add(o);
}
@Override
public void removeObserver(Observer o) {
int i = observers.indexOf(o);
if(i>=0)
observers.remove(i);
}
@Override
public void notifyObservers() {
for (int i = 0; i
Observer observer = (Observer) observers.get(i);
observer.update(temperture, humidity, pressure);
}
}
//当气象站得到更新观测值时,通知观察者
public void measurementsChanged(){
notifyObservers();
}
public void setMeasurements(float temperature,float humidity,float pressure){
this.temperture=temperature;
this.humidity=humidity;
this.pressure=pressure;
measurementsChanged();
}
}
具体观察者CurrentConditionDisplay:
public class CurrentConditionsDislpay
implements Observer, DisplayElement {
private float temperture;
private float humidity;
private Subject weatherData;
public CurrentConditionsDislpay(Subject weatherData) {
this.weatherData=weatherData;
weatherData.registerObserver(this);
}
@Override
public void update(float temperture, float humidity, float pressure) {
this.humidity=humidity;
this.temperture=temperture;
display();
}
@Override
public void display() {
System.out.println("Current conditions:"+temperture+"F degrees and "+humidity+"% humidity");
}
}
测试类TestObserver:
public class TestObserver {
public static void main(String[] args) {
WeatherData weatherData = new WeatherData();
CurrentConditionsDislpay currentDisplay = new CurrentConditionsDislpay(weatherData);
weatherData.setMeasurements(80, 65, 30.4f);
}
}
例子二:使用JAVA内置的支持实现
具体主题类WeatherData:import java.util.Observable;
public class WeatherData extends Observable{
private float temperture;
private float humidity;
private float pressure;
public WeatherData() {
}
//当气象站得到更新观测值时,通知观察者
public void measurementsChanged(){
setChanged();
notifyObservers();
}
public void setMeasurements(float temperature,float humidity,float pressure){
this.temperture=temperature;
this.humidity=humidity;
this.pressure=pressure;
measurementsChanged();
}
public float getTemperture() {
return temperture;
}
public void setTemperture(float temperture) {
this.temperture = temperture;
}
public float getHumidity() {
return humidity;
}
public void setHumidity(float humidity) {
this.humidity = humidity;
}
public float getPressure() {
return pressure;
}
public void setPressure(float pressure) {
this.pressure = pressure;
}
}
具体观察者:import java.util.Observable;
import java.util.Observer;
public class CurrentConditionsDislpay implements Observer, displayElement {
private float temperture;
private float humidity;
Observable observable;
public CurrentConditionsDislpay(Observable observable) {
this.observable=observable;
observable.addObserver(this);
}
@Override
public void display() {
System.out.println("Current conditions:"+temperture+"F degrees and "+humidity+"% humidity");
}
@Override
public void update(Observable o, Object arg) {
if(o instanceof WeatherData){
WeatherData weatherData = (WeatherData) o;
this.temperture=weatherData.getTemperture();
this.humidity=weatherData.getHumidity();
display();
}
}
}
测试类和所需要的接口DisplayElement和手动实现的相同。
三、设计原则
1.找出程序中会变化的方面,然后将其和固定不变的方面相分离。
在观察者模式中,会改变的是主题的状态,以及观察者的数目和类型。用这个模式,你可以改变依赖与主题状态的对象,却不必改变主题。这为提前规划。
2.针对接口编程,不针对实现编程
主题与观察者都使用接口,观察者利用主题的接口向主题注册,而主题利用观察者接口通知观察者,这样可以让两者之间运作正常,又同时具有松耦合的优点。
3.多组合,少继承
观察者模式利用组合将许多观察者组合进主题中,对象之间的这种关系不是通过继承产生的,而是在运行时利用组合的方式产生的。
本文由职坐标整理并发布,希望对同学们有所帮助。了解更多详情请关注编程语言JAVA频道!