1.定义
又叫发布订阅模式,定义对象间一种一对多的依赖关系,使得每当一个对象改变状态,所有依赖于他上午对象都会得到通知并自动更新。
观察者模式就像一个聊天室,当你需要收到聊天室的消息时,就注册成为聊天室的成员,当聊天室有信息更新时,就会传到你那。当你不需要接收聊天室的消息时,就注销退出聊天室 。又例如,天气观测站和气象报告板的关系。但报告板想获取观测站的数据,可以注册加入到观测站的观察者列表中,这就可以使观测站有数据更新时,自动传给气象报告板。
2.要创建的三个接口
(1)Subject接口:用于指定天气观测站(数据源)应该具有的方法
addObserver() :用于加入一个气象报告板(观察站)到观察者列表中
deleteObserver() :用于从观察者列表中删除一个观察者
notifyObservers() :用于向观察者列表的所有观察者发送数据
setChanged() :当调用 notifyObserver() 之前,必须先调用一次setChanged()
(2)Observer接口:
update():从数据源获得数据后,调用update()更新报告版(观察者)的数据
(3)DisplayElement接口:
display():用于显示报告板的数据
3.实现接口
4.具体代码
(1)接口
public interface Subject {
public void addObserver(Observer o);
public void removeObserver(Observer o);
public void notifyObservers();
}
public interface Observer {
public void update(String s);
}
public interface DisplayElement {
public void display();
}
(2)接口实现
package com.example.observertest;
import java.util.ArrayList;
public class WeatherData implements Subject {
ArrayList<Observer> observers=new ArrayList<>();
String weather;
public WeatherData(){
}
@Override
public void addObserver(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<observers.size();i++){
observers.get(i).update(weather);
}
}
public void setWeather(String weather){
this.weather=weather;
notifyObservers();//有了新数据就发送数据
}
}
package com.example.observertest;
public class ConditionDisplay implements Observer,DisplayElement {
public String mName;
public String mWeather;
public ConditionDisplay(String name){//初始化的时候需要指定数据源和观察者的名字
mName=name;
}
@Override
public void display() {
System.out.println(mName+":"+mWeather);
}
@Override
public void update(String weather) {
mWeather=weather;
display();
}
}
main:
package com.example.observertest;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
WeatherData weatherData1=new WeatherData();
ConditionDisplay conditionDisplay1=new ConditionDisplay("observe1");
ConditionDisplay conditionDisplay2=new ConditionDisplay("observe2");
weatherData1.addObserver(conditionDisplay1);
weatherData1.addObserver(conditionDisplay2);
weatherData1.setWeather("晴朗");
weatherData1.setWeather("rain");
}
}
5.java内置的Observer
被观察者extendsObservable类调用setChanged、notifyObservers方法,观察者实现 Observer、DisplayMent 接口的update方法;
import java.util.Observable;
import java.util.Observer;
public class ConditiondisplayJavaTest implements Observer {
String mName;
WeatherDataJavaTest mWeatherData;
public ConditiondisplayJavaTest(WeatherDataJavaTest weatherDataJavaTest,String name){
mName=name;
mWeatherData=weatherDataJavaTest;
mWeatherData.addObserver(this);
}
@Override
public void update(Observable observable, Object o) {
System.out.println(mName+o);
}
}
public class WeatherDataJavaTest extends Observable {
public String mWeatherData;
public void setDate(String weatherData){
mWeatherData=weatherData;
setChanged();
notifyObservers(mWeatherData);
}
}
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
WeatherDataJavaTest weatherDataJavaTest=new WeatherDataJavaTest();
ConditiondisplayJavaTest conditiondisplayJavaTest=new ConditiondisplayJavaTest(weatherDataJavaTest,"observer1");
weatherDataJavaTest.setDate("晴朗");
}
}
(3)Java中源码