//目标对象:天气对象WeatherSubject.java
import java.util.List;
import java.util.ArrayList;
/*
*目标对象知道观察它的观察者,并提供注册(添加)和删除观察者的接口
* */
public class WeatherSubject {
//用来保存注册的观察者对象
private List<Observer> observers = new ArrayList<Observer>();
//把订阅天气的人添加到列表中
//attach detach notifyObservers;
public void attach(Observer observer)
{
observers.add(observer);
}
//删除集合中的指定观察者
public void detach(Observer observer) {
observers.remove(observers);
}
//通知所有注册的观察者对象,只有子类才可以调用
//拉模式:让观察者自己取内容
// protected void notifyObservers() {
// for(Observer observer:observers) {
// observer.update(this);
// }
// }
//推模式:指定内容
protected void notifyObservers(String context) {
for(Observer observer:observers) {
observer.update(context);
}
}
}
//具体的目标对象 WeatherConcreteSubject.java
/*
*具体的目标对象,负责把有关状态存入到相应的观察者对象中
*/
public class WeatherConcreteSubject extends WeatherSubject {
/**
* 获取天气的内容信息
*/
private String weatherContext;
public String getWeatherContext() {
return weatherContext;
}
//拉模型
// public void setWeatherContext(String weatherContext) {
// this.weatherContext = weatherContext;
// //内容有了,说明天气更新了,通知所有订阅的人
// this.notifyObservers();
// }
//推模型
public void setWeatherContext(String weatherContext)
{
this.weatherContext = weatherContext;
this.notifyObservers(weatherContext);
}
}
//观察者对象:Observer.java
/*这是一个观察者接口,定义一个更新接口给哪些在目标发生改变的时候被通知的对象。
* */
public interface Observer {
//传入目标对象,方便获取相应的目标对象的状态。
//拉模式
//public void update(WeatherSubject subject);
//推模式:按需分配的内容
public void update(String context);
}
//具体观察者对象:ConcreteObserver.java
public class ConcreteObserver implements Observer {
//观察者的名字,是谁收到了这个讯息,
private String observerName;
//天气内容的情况,这个消息从目标处获取
private String weatherContext;
//提醒的内容:黄明的女朋友提醒约会,他的老妈提醒购物
private String remindThing;
private String observerState;
/*
* 获取目标类的状态同步到观察者的状态中*/
@Override
//拉模式
// public void update(WeatherSubject subject) {
// // TODO Auto-generated method stub
// weatherContext = ((WeatherConcreteSubject)subject).getWeatherContext();
// System.out.println(observerName + "收到了"+weatherContext + ","+remindThing);
// }
//推模式:按需取内容
public void update(String context) {
weatherContext = context;
System.out.println(observerName + "收到了" + weatherContext + ","+remindThing);
}
public String getObserverName() {
return observerName;
}
public void setObserverName(String observerName) {
this.observerName = observerName;
}
public String getWeatherContext() {
return weatherContext;
}
public void setWeatherContext(String weatherContext) {
this.weatherContext = weatherContext;
}
public String getRemindThing() {
return remindThing;
}
public void setRemindThing(String remindThing) {
this.remindThing = remindThing;
}
}
//测试类:Client.java
/*
*观察者模式实现的俩种方式:
* 推模型:目标对象主动向观察者推送目标推送目标的详细信息;推送的信息通畅是目标对象的全部或部分数据;(假定目标对象是直到观察者需要的数据)
* 拉模型:目标对象在通知观察者的时候,只传递少量信息;如果观察者需要更具体的信息,由观察者主动到目标对象中获取,相当于观察者从目标对象中拉数据
* 一般这种模型的实现中,会把目标对象自身通过update方法传递给观察者
* */
public class Client {
public static void main(String[] args) {
//创建目标
WeatherConcreteSubject weather = new WeatherConcreteSubject();
//创建观察者
ConcreteObserver obserGirl = new ConcreteObserver();
obserGirl.setObserverName("黄明的女朋友");
obserGirl.setRemindThing("是我们第一次约会,地点街心公园,不见不散哦");
ConcreteObserver observerMum = new ConcreteObserver();
observerMum.setObserverName("老妈");
observerMum.setRemindThing("是个购物的好日子,明天去天虹扫货");
//注册观察者
weather.attach(obserGirl);
weather.attach(observerMum);
//目标发布天气
weather.setWeatherContext("明天天气晴朗,蓝天白云,气温28度");
}
}