观察者模式(二)

来源:互联网 发布:用友软件维护合同 编辑:程序博客网 时间:2024/05/16 06:46

观察者模式的定义
定义对象间的一种一对多的依赖关系。当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。
这里写图片描述
这里写图片描述
认识观察者模式的六大方面:
1、目标与观察者之间的关系:一对多、一对一、多对一(要区分update方法)
2、单向依赖
3、命名建议,subject、observer、update
4、触发通知的时机:先改数据再触发,在setWeatherContent中先设置内容值,再通知notifyObservers
5、观察者模式的调用顺序示意图:
准备阶段:创建目标对象–创建观察者对象–向目标对象注册观察者对象
运行阶段:改变目标对象的状态setWeatherContent–通知所有注册的观察者对象进行相应的处理notifyObservers–回调目标对象,获取相应的数据update
6、通知的顺序
不确定,平行的,没有相互依赖关系

两种模型的比较:
推模型是假定目标对象知道观察着需要的数据
拉模型是目标对象不知道观察着具体需要什么数据,因此把自身传给观察者,由观察者来取值
推模型会使观察者对象难于复用。
拉模型下,update方法的参数是目标对象本身,基本上可以适应于各种情况的需要。

Java 实现 VS 自己实现的对比4点
(1)不需要再定义观察者和目标接口(JDK已经定义)
(2)具体的目标实现里面不需要再维护观察者的注册信息,Java中的Observable类里面已经实现0A(3)触发通知的方式有一点变化,要先调用setChanged方法,这个是Java为了帮助实现更精确的触发控制而提供的功能。
(4)具体观察者的实现里面,update方法其实能同时支持推模型和拉模型,这个Java在定义的时候,已经考虑

观察者的优点
(1)观察者模式实现了观察者和目标之间的抽象耦合
(2)观察者模式实现了动态联动(一个操作会引起其他相关的操作)
(3)观察者模式支持广播通信
观察者的缺点
可能引起无谓的操作!

建议 在以下情况中选用观察者模式:
(1)当一个抽象模型有 2 个方面,其中一个方面的操作依赖于另一个方面的状态变化。
(2)如果在更改一个对象的时候,需要同时连带改变其他的对象,而且不知道究竟应该有多少对象需要被连带改变。
(3)当一个对象必须通知其他的对象,但是你又希望这个对象和其他被通知的对象是松散耦合

package weatherObserver;
import java.util.ArrayList;
import java.util.List;
public abstract class WeatherSubject {
//用来保存注册的观察者对象
public List observers = new ArrayList();
//把订阅天气的观察者添加到订阅者列表中
public void attach (Observer observer){
observers.add(observer);
}
//删除集合中指定的订阅天气的人
public void detach(Observer observer){
observers.remove(observer);
}
public abstract void notifyObservers();
}
package weatherObserver;
public class ConcreteWeatherSubject extends WeatherSubject{
private String weatherContent;
public void notifyObservers() {
for(Observer observer:observers ){
if( “下雨”.equals(this .getWeatherContent())){
if( “黄明的女朋友” .equals(observer .getObserverName())){
observer.update(this );
}
if( “黄明的老妈” .equals(observer .getObserverName())){
observer.update(this );
}
}
if( “下雪”.equals(this .getWeatherContent())){
if( “黄明的老妈” .equals(observer .getObserverName())){
observer.update(this );
}
}
}
}
public String getWeatherContent() {
return weatherContent;
}
public void setWeatherContent(String weatherContent) {
this. weatherContent = weatherContent;
this.notifyObservers();
}
}
package weatherObserver;
//定义一个更新的接口方法给那些在目标发生改变的时候被通知的观察者对象调用
public interface Observer {
//更新的接口
public void update(WeatherSubject subject);
//设置观察者名称
public void setObserverName(String observerName);
//取得观察者名称
public String getObserverName();
}
package weatherObserver;
public class ConcreteObserver implements Observer{
//观察者的名称
private String observerName;
//天气情况的内容
private String weatherContent;
//提醒内容
private String remindThing;
@Override
public void update(WeatherSubject subject) {
weatherContent = ((ConcreteWeatherSubject)subject).getWeatherContent();
System.out.println(observerName+ “收到了”+weatherContent+”:” +remindThing);
}
@Override
public void setObserverName(String observerName) {
this.observerName = observerName;
}
@Override
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;
}
}
package weatherObserver;
public class Client {
public static void main(String[] args) {
//1.创建目标
ConcreteWeatherSubject weatherSubject = new ConcreteWeatherSubject();
//2.创建观察者
ConcreteObserver observerGirl = new ConcreteObserver();
observerGirl.setObserverName( “黄明的女朋友” );
observerGirl.setRemindThing( “下雨了,安静的待在家” );
ConcreteObserver observerMum = new ConcreteObserver();
observerMum.setObserverName( “黄明的老妈” );
observerMum.setRemindThing( “我都不出门” );
//3.注册观察者
weatherSubject.attach( observerGirl);
weatherSubject.attach( observerMum);
//4.目标发布天气了
weatherSubject.setWeatherContent( “下雨”);
}
}

0 0
原创粉丝点击