当对象间存在多对一的依赖关系时,可以使用观察者模式(Observer Pattern)。观察者模式属于行为型模式。
概况的说就是:一个类(被观察者Observable)管理着所有依赖于它的类(观察者Observer),并且它状态变化时会主动给这些依赖它的类发出通知。
自定义观察者模式的demo:
观察者接口:
public interface Observer {
void update(Observable o);
}
具体的观察者类:
public class ObserverMomo implements Observer {
@Override
public void update(Observable observable) {
System.out.println("观察者1知道了" + observable.getClass().getSimpleName() + "发生了变化");
}
}
被观察者:
public class Observable {
List<Observer> observers = new ArrayList<>();
public void addObserver(Observer observer) {
observers.add(observer);
}
public void changed() {
notifyObservers();
}
private void notifyObservers() {
for (Observer observer : observers) {
observer.update(this);
}
}
}
调用:
Observable observable = new Observable();
observable.addObserver(new ObserverMomo());
observable.changed();
使用JDk提供的java.util.Observable和java.util.Observer写的的读者订阅作者的demo:
读者类:
public class Reader implements Observer {
private String readerName;
public Reader(String readerName) {
this.readerName = readerName;
}
// 订阅作者,也就是通过作者姓名在WriterManager中获取到作者对象,然后把自己添加到这个作者的观察者列表中
public void subscribe(String writerName) {
WriterManager.getInstance().getWriter(writerName).addObserver(this);
}
// 取消订阅
public void unSubscribe(String writerName) {
WriterManager.getInstance().getWriter(writerName).deleteObserver(this);
}
@Override
public void update(Observable observable, Object arg) {
if (observable instanceof Writer) {
Writer writer = (Writer) observable;
System.out.println(readerName + "知道了作者" + writer.getWriterName() + "的新书的信息是" + writer.getNewBook());
}
}
}
作者类:
public class Writer extends Observable {
private String writerName;
private String newBook;
public Writer(String writerName) {
super();
this.writerName = writerName;
WriterManager.getInstance().add(this);
}
public String getWriterName() {
return writerName;
}
public String getNewBook() {
return newBook;
}
// 发布新书,通知读者
public void PublishNewBook(String newBook) {
this.newBook = newBook;
// 一定要调用setChanged方法,然后再调用notifyObservers方法
setChanged();
notifyObservers();
}
}
管理作者列表:
public class WriterManager {
// 作者列表
private Map<String, Writer> writerMap = new HashMap<>();
// 添加作者
public void add(Writer writer) {
writerMap.put(writer.getWriterName(), writer);
}
// 根据作者姓名获取作者对象
public Writer getWriter(String writerName) {
return writerMap.get(writerName);
}
// 单例
private WriterManager() {
}
public static WriterManager getInstance() {
return WriterManagerInstance.instance;
}
private static class WriterManagerInstance {
private static WriterManager instance = new WriterManager();
}
}
源码分析:
观察者接口
package java.util;
public interface Observer {
// arg变量是可以选择调用有参的notifyObservers传过来的附加参数
void update(Observable o, Object arg);
}
被观察者类
package java.util;
public class Observable {
private boolean changed = false;
private final ArrayList<Observer> observers;
public Observable() {
observers = new ArrayList<>();
}
public synchronized void addObserver(Observer o) {
if (o == null)
throw new NullPointerException();
if (!observers.contains(o)) {
observers.add(o);
}
}
public synchronized void deleteObserver(Observer o) {
observers.remove(o);
}
public void notifyObservers() {
notifyObservers(null);
}
// 通知观察者
public void notifyObservers(Object arg) {
Observer[] arrLocal;
synchronized (this) {
// 如果没有变化,直接return就不会通知观察者了
if (!hasChanged())
return;
arrLocal = observers.toArray(new Observer[observers.size()]);
clearChanged();
}
for (int i = arrLocal.length-1; i>=0; i--)
arrLocal[i].update(this, arg);
}
public synchronized void deleteObservers() {
observers.clear();
}
protected synchronized void setChanged() {
changed = true;
}
protected synchronized void clearChanged() {
changed = false;
}
public synchronized boolean hasChanged() {
return changed;
}
public synchronized int countObservers() {
return observers.size();
}
}