本文是对文中参考文献的学习笔记
一、作用
观察者模式描述了一对多的关系。当一个对象的状态改变时,它的所有观察者都可收到通知并进行相应更新。
二、概念
UML三、使用
1.抽象出被观察者java.util.Observable
实际使用时该抽象类/接口可省略
手动敲了下
java.util.Observable
,它是一个 class 而不是接口,鸿洋如是说:"基本上书上都对于Java的如此设计抱有反面的态度,觉得Java内置的观察者模式,违法了面向接口编程这个原则,但是如果转念想一想,的确你拿一个主题在这写观察者模式(我们自己的实现),接口的思想很好,但是如果现在继续添加很多个主题,每个主题的ddObserver,removeObserver,notifyObservers代码基本都是相同的吧,接口是无法实现代码复用的,而且也没有办法使用组合的模式实现这三个方法的复用,所以我觉得这里把这三个方法在类中实现是合理的"
/**
* 重新调整了java.util.Observable的结构
* @author yanglijin
* @version v1.0
* @since 2019-09-04
*/
public class Observable {
// 标志被观察者是否有变化
private boolean changed = false;
private Vector < Object > obs;
// 构建一个有0个观察者的被观察者
public Observable() {
obs = new Vector < > ();
}
// 1,管理观察者
/**
* 添加观察者
* @param o an observer to be added.
* @throws NullPointerException 如果添加的o为null时,会抛出异常
*/
public synchronized void addObserver(Observer o) {
if (o == null) {
throw new NullPointerException();
}
if (!obs.contains(o)) {
obs.addElement(o);
}
}
/**
* 删除观察者
* @param o:传入null 对该方法无影响
*/
public synchronized void deleteObserver(Observer o) {
obs.removeElement(o);
}
// 2,对象状态变化时通知观察值
public void notifyObservers() {
notifyObservers(null);
}
/**
*
* @param arg:通知被观察者时携带的参数
*/
public void notifyObservers(Object arg) {
Object[] arrLocal;
synchronized(this) {
if (!hasChange()) {
return;
}
arrLocal = obs.toArray();
clearChanged();
}
for (int i = arrLocal.length - 1; i >= 0; i--) {
((Observer) arrLocal[i]).update(this, arg);
}
}
public synchronized void setChanged() {
changed = true;
}
public synchronized boolean hasChange() {
return changed;
}
public synchronized void clearChanged() {
changed = false;
}
public synchronized int countObservers() {
return obs.size();
}
}
2.实现具体的被观察者
public class MyBookManager extends Observable {
private List<Book> mBooks;
// 构造一个空的图书集合
public MyBookManager(){
mBooks = new ArrayList<>();
}
public void addBook(Book newBook) {
mBooks.add(newBook);
// 通知观察者
setChanged();
notifyObservers(newBook);
}
}
3.抽象观察者
观察者具有的操作接口
public interface Observer {
/**
*
* @param var1:被观察者对象
* @param var2:传递给观察者的参数
*/
void update(Observable var1, Object var2);
}
4.具体观察者
public class User implements Observer {
private String userName;
public User(String userName) {
this.userName = userName;
}
@Override
public void update(Observable observable, Object o) {
if (o instanceof Book) {
Book book = (Book) o;
System.out.println(userName+"收到新书达到通知:"+book.toString());
}
}
}
5. 测试
@Test
public void testObserver() {
MyBookManager bookManager = new MyBookManager();
bookManager.addObserver(new User("小红"));
bookManager.addObserver(new User("小明"));
bookManager.addBook(new Book(1, "穆斯林的葬礼"));
}
小明收到新书达到通知:Book{id=1, name='穆斯林的葬礼'}
小红收到新书达到通知:Book{id=1, name='穆斯林的葬礼'}
参考文献
观察者模式 : 一支穿云箭,千军万马来相见
设计模式之观察者模式源码分析及实践
观察者设计模式在Android开发中的应用
网友评论