定义
观察者模式定义了对象之间的一对多依赖,这样一来,当一个对象状态改变时,他的所有的依赖者都会收到通知并自动更新。
使用场景
观察者模式是典型的发布——订阅模式,通过两个对象间的松耦合方式结合,经常用于解耦。
在观察者模式中,主题对象(Subject)和观察者对象(Observer)之间是一对多的关系,当主题对象的状态之间有变化,观察者就会被通知,从而完成更新。
观察者模式经常用于GUI系统,如Android中的ListView。
UML类图
其UML类图如下:

示例
中秋节快要来了,其中某地的学校、工厂、医院都在等政府的放假通知,当政府发出通知后,这几个单位将同时得到通知内容。这时我们可以通过观察者模式来实现,其中政府是一个主题对象,而学校、医院、工厂是观察者:
- Step1.首先定义主题接口和观察者接口:
public interface Subject {
void registObserver(Observer o);
void unregistObserver(Observer o);
void notifyChanged(String str);
}
public interface Observer {
void onChanged(String str);
}
- Step2.定义具体的主题类和观察者类:
package com.jyq.observer;
import java.util.ArrayList;
public class Government implements Subject {
//用来存储观察者
private ArrayList<Observer> observers = new ArrayList<>();
//注册一个观察者
@Override
public void registObserver(Observer o) {
// TODO Auto-generated method stub
if (observers.indexOf(o) < 0) {
observers.add(o);
}
}
//取消注册观察者
@Override
public void unregistObserver(Observer o) {
// TODO Auto-generated method stub
int i = observers.indexOf(o);
if (i >= 0) {
observers.remove(i);
}
}
//通知所有观察者
@Override
public void notifyChanged(String str) {
// TODO Auto-generated method stub
for(int i=0; i<observers.size();i++) {
observers.get(i).onChanged(str);
}
}
}
public class School implements Observer {
public School(Subject subject) {
subject.registObserver(this);
}
@Override
public void onChanged(String str) {
// TODO Auto-generated method stub
System.out.println("School:"+str);
}
}
public class Hospital implements Observer {
public Hospital(Subject subject) {
subject.registObserver(this);
}
@Override
public void onChanged(String str) {
// TODO Auto-generated method stub
System.out.println("Hospital:"+str);
}
}
public class Factory implements Observer {
public Factory(Subject subject) {
subject.registObserver(this);
}
@Override
public void onChanged(String str) {
// TODO Auto-generated method stub
System.out.println("Factory:"+str);
}
}
- Step3.主题对象状态发生改变,于是通知观察者:
public class DemoObserverDesign {
public static void main(String[] args) {
// TODO Auto-generated method stub
Government government = new Government();
School higSchool = new School(government);
Hospital hospital = new Hospital(government);
Factory factory = new Factory(government);
government.notifyChanged("今年中秋,放假10天!");
}
}
运行程序,输出结果如下:
School:今年中秋,放假10天!
Hospital:今年中秋,放假10天!
Factory:今年中秋,放假10天!
总结
- 1.观察者模式定了对象间一对多的关系,一个主题对应多个观察者;
- 2.在观察者模式中,主题和观察者都使用接口,针对接口编程,而非针对实现编程;
- 3.观察者和主题对象通过松耦合实现,主题对象唯一知道关于观察者对象的就是其实现了观察者接口;
- 4.观察者模式中,利用组合将观察者对象组合进了主题中。
关于java内置的观察者模式
从JDK1.0开始,java中就内置了观察者模式:
import java.util.Observable;
import java.util.Observer;
其中java.util.Observable是主题对象的基类,如果要通过java内置API实现观察者模式,则主题对象需要继承Observable类。java.util.Observer则是观察者接口,所有的观察者需要实现该接口,如果将示例通过java内置API来实现,则类结构如下:
import java.util.ArrayList;
import java.util.Observable;
public class Government extends Observable {
public void sendMsg() {
setChanged();
//通知所有观察者
notifyObservers();
}
}
import java.util.Observable;
import java.util.Observer;
public class School implements Observer {
public School(Observable observerable) {
observerable.addObserver(this);
}
@Override
public void update(Observable o, Object arg) {
// TODO Auto-generated method stub
System.out.println("School:");
}
}
然而这个API并不常用,原因在于若使用该API,则主题对象必须继承java.util.Observable,因此就限制了主题类的复用能力。
2万+

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



