观察者模式很好理解,类似于邮件订阅和RSS订阅,当我们浏览一些博客或wiki时,经常会看到RSS图标,就这的意思是,当你订阅了该文章,如果后续有更新,会及时通知你。其实,简单来讲就一句话:当一个对象变化时,其它依赖该对象的对象都会收到通知,并且随着变化!对象之间是一种一对多的关系。这里把RSS订阅改称为“主题”(Subject),订阅者改称为“观察者”(Observer)。
看实现代码:
定义观察者接口:public interface IObserver {
void update();
} 观察者实现类:public class ObserverAImpl implements IObserver {
@Override
public void update() {
System.out.println("ObserverA update()! ");
}
}public class ObserverBImpl implements IObserver {
@Override
public void update() {
System.out.println("ObserverB update()! ");
}
} 定义主题接口:public interface ISubject {
void addObserver(IObserver o);
void removeObserver(IObserver o);
void notifyObserver();
} 主题实现类:public class RssSubjectImpl implements ISubject {
private ArrayList observerList;
public RssSubjectImpl() {
observerList = new ArrayList<IObserver>();
}
@Override
public void addObserver(IObserver o) {
observerList.add(o);
}
@Override
public void removeObserver(IObserver o) {
int i = observerList.indexOf(o);
if (i >= 0) {
observerList.remove(i);
}
}
@Override
public void notifyObserver() {
for (int i = 0; i < observerList.size(); i++) {
IObserver observer = (IObserver) observerList.get(i);
observer.update();
}
}
public void change() {
notifyObserver();
}
} 测试:public static void main(String[] args) {
RssSubjectImpl subject = new RssSubjectImpl();
IObserver observerA = new ObserverAImpl();
IObserver observerB = new ObserverBImpl();
subject.addObserver(observerA);
subject.change();
System.out.println();
subject.addObserver(observerB);
subject.change();
} 运行结果:ObserverA update()!
ObserverA update()!
ObserverB update()!
每次主题调用change()时,注册在该主题的观察者就会有相应的动作。可不可以这样呢,当主题某一数据发生改变时,不用显式地调用change(),关注该主题的观察者就能接收到数据的变化。
如下示例:public interface IObserver {
void update(ISubject subject);
}
public class ObserverAImpl implements IObserver {
private ISubject subject;
@Override
public void update(ISubject subject) {
if (subject instanceof RssSubjectImpl) {
RssSubjectImpl weatherSubject = (RssSubjectImpl) subject;
System.out.println("ObserverA update()! getA()="
+ weatherSubject.getA());
System.out.println("ObserverA update()! getB()="
+ weatherSubject.getB());
}
}
}
public class ObserverBImpl implements IObserver {
private ISubject subject;
@Override
public void update(ISubject subject) {
if (subject instanceof RssSubjectImpl) {
RssSubjectImpl weatherSubject = (RssSubjectImpl) subject;
System.out.println("ObserverB update()! getA()="
+ weatherSubject.getA());
System.out.println("ObserverB update()! getB()="
+ weatherSubject.getB());
}
}
}
public interface ISubject {
void addObserver(IObserver o);
void removeObserver(IObserver o);
void notifyObserver();
}
public class RssSubjectImpl implements ISubject {
private ArrayList observerList;
private int a;
private int b;
private boolean hasChanged = false;
public RssSubjectImpl() {
observerList = new ArrayList<IObserver>();
}
@Override
public void addObserver(IObserver o) {
observerList.add(o);
}
@Override
public void removeObserver(IObserver o) {
observerList.remove(o);
}
@Override
public void notifyObserver() {
for (int i = 0; i < observerList.size(); i++) {
IObserver observer = (IObserver) observerList.get(i);
observer.update(this);
}
}
public void setA(int a) {
this.a = a;
hasChanged = true;
change();
}
public void setB(int b) {
this.b = b;
hasChanged = true;
change();
}
public int getA() {
return this.a;
}
public int getB() {
return this.b;
}
public void change() {
if (hasChanged) {
notifyObserver();
}
hasChanged = false;
}
}
测试: public static void main(String[] args) {
RssSubjectImpl subject = new RssSubjectImpl();
IObserver observerA = new ObserverAImpl();
IObserver observerB = new ObserverBImpl();
subject.addObserver(observerA);
subject.setA(8);
System.out.println();
subject.addObserver(observerB);
subject.setB(8);
System.out.println("*********************");
subject.setA(7);
} 运行结果:ObserverA update()! getA()=8
ObserverA update()! getB()=0
ObserverA update()! getA()=8
ObserverA update()! getB()=8
ObserverB update()! getA()=8
ObserverB update()! getB()=8
*********************
ObserverA update()! getA()=7
ObserverA update()! getB()=8
ObserverB update()! getA()=7
ObserverB update()! getB()=8Java也内置了实现观察者模式的类与接口,java.util.Observable类,Observable是一个抽象的主题对象。如果它被改变了,它必须调用setChanged()方法。当它准备通知它的改变时,它必须调用notifyObservers()方法,这导致了在观测对象中对update()方法的调用。如果在调用notifyObservers()方法之前没有调用setChanged()方法,就不会有什么动作发生。java.util.Observer接口。此接口中只有一个方法:void update(Observable o, Object arg) ,这个方法在被观察对象(Observable类)的notifyObservers()方法中被调用。
示例:
public class Subject extends Observable {
public void countdown(int number) {
// 设置改变变量
setChanged();
// 通知所有观察者,将number作为参数信息传递给观察者
notifyObservers(number);
}
}
public class ObserverA implements Observer {
public void update(Observable o, java.lang.Object arg) {
// TODO Auto-generated method stub
System.out.println("ObserverA "+arg);
}
}
public class ObserverB implements Observer {
public void update(Observable o, Object arg) {
// TODO Auto-generated method stub
System.out.println("ObserverB " + arg);
}
}
public class Test {
public static void main(String[] args) {
// TODO Auto-generated method stub
Subject subject = new Subject();
subject.addObserver(new ObserverA());
subject.addObserver(new ObserverB());
subject.countdown(7);
}
}
本文详细介绍了观察者模式的原理及应用场景,通过实例演示了如何利用该模式实现对象间的依赖关系,包括自定义实现和使用Java内置类两种方式。
1049

被折叠的 条评论
为什么被折叠?



