设计模式学习笔记:观察者模式
Posted 滴滴哒滴哒
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了设计模式学习笔记:观察者模式相关的知识,希望对你有一定的参考价值。
上一篇的观察者模式的笔记中提到的例子,只是Subject把自身状态“推”给Observer的方式。 //通知观察者信息发生改变了
@Override
public void notifyObservers()
for (int i = 0;i < observers.size();i++)
Observer observer = (Observer) observers.get(i);
observer.update(travelerNum,terminal,information);
//更新旅行信息
public void setTravelInformation(int travelerNum,String terminal,String information)
this.travelerNum = travelerNum;
this.information = information;
this.terminal = terminal;
notifyObservers();
从代码中可以看出,只要Subject发生改变,Observer就会被动接受全部信息,并且不得不接受。
这种模式的优势在于:Observer不用调用多次,才收集全所有需要的消息。
同时这种模式会造成一定的麻烦:
1、Observer可能并不需要所有的消息;
2、在Subject需要扩展时,需要更新每一个发送给Observer的消息 。
这时我们可以在Subject中提供一些公开的getter方法,让Observer自己索取所需要的信息。
在这里我们还是选取旅行者的例子。
Subject/Observable接口:
public interface Observable
public void registerObserver(Observer o);
public void removeObserver(Observer o);
public void notifyObservers();
Observer接口:
public interface PrepareTravel
void doPrepare();
用来展示的接口PrepareTravel():
public interface PrepareTravel
void doPrepare();
Organizer去实现Obserable接口:
public class Organizer implements Observable
//标记Subject状态是否发生改变
private boolean changed;
//旅行者人数
private int travelerNum;
//目的地
private String terminal;
//相关信息
private String information;
//用于存放observers的数组
private ArrayList observers;
//构造器
public Organizer()
//初始化observers,否则会报空指针
observers = new ArrayList();
//标记默认为false,未发生改变
changed = false;
//注册observer
@Override
public void registerObserver(Observer o)
observers.add(o);
//删除observer
@Override
public void removeObserver(Observer o)
int i = observers.indexOf(o);
if (i >= 0)
observers.remove(i);
//通知observer
@Override
public void notifyObservers()
if (changed)
for (int i = 0;i < observers.size();i++)
Observer observer = (Observer) observers.get(i);
observer.update(this);
changed = false;
//改变发生
public void setInformationChanged(int travelerNum,String terminal,String information)
changed = true;
this.travelerNum = travelerNum;
this.terminal = terminal;
this.information = information;
notifyObservers();
//公共的getter方法供observer去“拉”所需要的信息
public int getTravelerNum()
return travelerNum;
public String getTerminal()
return terminal;
public String getInformation()
return information;
在这里我们引进了changed标记,使得更新观察者时,拥有更多的弹性。在这个场景中,我们并不想每加一个人都通知观察者Traveler,我们想变更达到10人才通知观察者Traveler。我们可以添加条件:
//改变发生
public void setInformationChanged(int travelerNum,String terminal,String information)
if (travelerNum - this.travelerNum >= 10)
changed = true;
this.travelerNum = travelerNum;
this.terminal = terminal;
this.information = information;
notifyObservers();
Traveler去实现Observer接口:
public class Traveler implements Observer,PrepareTravel
//Subject
Observable observable;
//旅客人数
private int travelerNum;
//目的地
private String terminal;
//相关信息
private String information;
//构造器
public Traveler(Observable observable)
this.observable = observable;
//注册
observable.registerObserver(this);
//更新自己所需要的信息
@Override
public void update(Observable o)
if (o instanceof Organizer)
Organizer organizer = (Organizer) o;
//可以“拉”自身所需要的信息
this.travelerNum = organizer.getTravelerNum();
this.terminal = organizer.getTerminal();
this.information = organizer.getInformation();
doPrepare();
//展示
@Override
public void doPrepare()
System.out.println("我已知悉这次旅行有"+travelerNum+"人,前往"+terminal+",其他相关信息有"+information);
模拟旅行:
public class TravelSimulator
public static void main(String[] args)
Organizer organizer = new Organizer();
Traveler traveler = new Traveler(organizer);
organizer.setInformationChanged(10,"九华山","安徽");
organizer.setInformationChanged(11,"黄山","安徽");
organizer.setInformationChanged(30,"峨眉山","四川");
添加changed条件前结果:
添加changed条件后结果:
《HeadFirst》中,推的方式被认为更正确(请教了大佬):有些实现中,会需要将改变前和改变后的值都放在通知里,这就没法用get了。
以上是关于设计模式学习笔记:观察者模式的主要内容,如果未能解决你的问题,请参考以下文章