观察者模式
定义:
定义对象间一种一对多的依赖关系,当一个对象的状态发生改变时,
所有依赖它的对象都会得到通知并且自动更新
观察者模式6大方面:
1,目标与观察者之间的关系
2,单向依赖
3,命令建议
第一 目标接口的定义,建议在名称后面跟Subject
第二 观察者接口的定义,建议在名称后面跟Observer
第三 观察者接口的更新方法,建议名称为update
4,触发通知的时机
5,观察者模式的调用顺序示意图
6,通知的顺序
观察者模式两种模式
1.推模型:目标对象主动向观察者推送目标的详细信息 ; 推送的信息通常是目标信息的全部或部分信息
2.拉模型:目标对象在通知观察者的时候,只传递少量信息 ;
如果观察者需要更具体的信息,由观察者主动到目标对象中获取,相当于是观察者从目标对象中拉数据;
一般这种模型的实现中,会把目标对象自身通过update方法传递给观察者。
比较:
推模型是假定目标对象知道观察着需要的数据
拉模型是目标对象不知道观察着具体需要什么数据,因此把自身传给观察者,由观察者来取值
java.util包中Observable类可以实现目标类
接口Observer定义了update()方法 可以实现观察者类
观察者模式的优点:
(1)观察者模式实现了观察者和目标之间的抽象耦合
(2)观察者模式实现了动态联动
(2)观察者模式支持广播通信
观察者模式的缺点:
可能会引起无谓的操作
建议在以下情况下使用观察者模式:触发联动
(1)当一个抽象模型有两个方面,其中一个方面的操作依赖于另一个方面的状态变化
(2)如果在更改一个对象的时候,需要同时连带改变其他的对象,而且不知道究竟应该 有多少对象需要被连带改变
定义:
定义对象间一种一对多的依赖关系,当一个对象的状态发生改变时,
所有依赖它的对象都会得到通知并且自动更新
观察者模式6大方面:
1,目标与观察者之间的关系
2,单向依赖
3,命令建议
第一 目标接口的定义,建议在名称后面跟Subject
第二 观察者接口的定义,建议在名称后面跟Observer
第三 观察者接口的更新方法,建议名称为update
4,触发通知的时机
5,观察者模式的调用顺序示意图
6,通知的顺序
观察者模式两种模式
1.推模型:目标对象主动向观察者推送目标的详细信息 ; 推送的信息通常是目标信息的全部或部分信息
2.拉模型:目标对象在通知观察者的时候,只传递少量信息 ;
如果观察者需要更具体的信息,由观察者主动到目标对象中获取,相当于是观察者从目标对象中拉数据;
一般这种模型的实现中,会把目标对象自身通过update方法传递给观察者。
比较:
推模型是假定目标对象知道观察着需要的数据
拉模型是目标对象不知道观察着具体需要什么数据,因此把自身传给观察者,由观察者来取值
java.util包中Observable类可以实现目标类
接口Observer定义了update()方法 可以实现观察者类
观察者模式的优点:
(1)观察者模式实现了观察者和目标之间的抽象耦合
(2)观察者模式实现了动态联动
(2)观察者模式支持广播通信
观察者模式的缺点:
可能会引起无谓的操作
建议在以下情况下使用观察者模式:触发联动
(1)当一个抽象模型有两个方面,其中一个方面的操作依赖于另一个方面的状态变化
(2)如果在更改一个对象的时候,需要同时连带改变其他的对象,而且不知道究竟应该 有多少对象需要被连带改变
(3) 当一个对象必须通知其他的对象,但是你又希望这个对象和其他的被通知的对象是松散耦合的
区别对待观察者的场景问题:即不同的观察者按照需求收到不同的信息
import java.util.ArrayList;
import java.util.List;
public abstract class WeatherSubject {
//用来保存注册的观察者对象
public List<Observer> observers=new ArrayList<Observer>();
//attach detach nnofiyObservers
public void attach(Observer observer){
observers.add(observer);
}
public void detach(Observer observer){
observers.remove(observer);
}
protected abstract void notifyObserver();
}
//定义一个更新的接口方法给那些目标发生变化的
public interface Observer {
//更新的接口
public void update(WeatherSubject subject);
//设置观察者名称
public void setObserverName(String observerName);
//取得观察者名称
public String getObserverName();
}
public class ConcreteWeatherSubject extends WeatherSubject {
//晴天,下雨,下雪
//目标对象的状态
private String weatherContent;
@Override
protected void notifyObserver() {
//循环所有注册的观察者
for(Observer ob:observers){
//规则是
//女朋友需要下雨通知,老妈需要下雨下雪通知
//如果是晴天,都不通知
//如果是下雨
if("下雨".equals(this.getWeatherContent())){
if("女朋友".equals(ob.getObserverName()))
ob.update(this);
if("老妈".equals(ob.getObserverName()))
ob.update(this);
}
//如果是下雪
if("下雪".equals(this.getWeatherContent())){
if("老妈".equals(ob.getObserverName()))
ob.update(this);
}
}
}
public class ConcreteObserver implements Observer {
//观察者的名称
private String observerName;
//天气情况的内容
private String weatherContent;
//提醒的内容
private String remindThing;
public void update(WeatherSubject subject) {
weatherContent=((ConcreteWeatherSubject)subject).getWeatherContent();
System.out.println(observerName+"收到了"+weatherContent+","+remindThing);
}
public void setObserverName(String observerName){
this.observerName=observerName;
}
//取得观察者名称
public String getObserverName(){
return observerName;
}
public String getWeatherContent() {
return weatherContent;
}
public void setWeatherContent(String weatherContent) {
this.weatherContent = weatherContent;
}
public String getRemindThing() {
return remindThing;
}
public void setRemindThing(String remindThing) {
this.remindThing = remindThing;
}
}
public class Client {
public static void main(String[] args) {
//创建目标
ConcreteWeatherSubject ws=new ConcreteWeatherSubject();
//创建观察者
ConcreteObserver girl=new ConcreteObserver();
girl.setObserverName("女朋友");
girl.setRemindThing("下雨了,在家吧");
ConcreteObserver mum=new ConcreteObserver();
mum.setObserverName("老妈");
mum.setRemindThing("我都不出门");
//注册观察者
ws.attach(girl);
ws.attach(mum);
//发布天气
ws.setWeatherContent("晴天");
}
}