对于观察者模式,其实在软件开发过程中并不陌生,它其实是一种发布订阅模式,是一种一对多的关系。当发布者发布了消息,订阅者可以收到相关的变换。在MQ和Zk中都存在这样的场景,也是使用比较多的一种模式。
观察者模式结构图:
网络盗图一张,观察者模式比较简单。
角色:
Subject:抽象主题(也就是抽象的被观察者),简答来理解就是它只提供一个接口,用于增加和删除观察者对象。其他不做什么。
ConcreteSubejct:具体主题(具体实现的被观察者),它的作用就是存储相关的状态,当状态改变时,发送通知给注册过的观察者。
Observer:抽象观察者,也是只负责提供更新接口,当主题状态变更时通知更新自己。
ConcreteOberver:具体观察者对象,实现接口,更新自己。
实现:
至于实现,想来想去,有个例子比较合适,就是微信的公众号,对于公众号来说,它本身是一个发布者,对于关注的人来说,就是订阅者。当发布者发布消息时,订阅者都能收到发布的消息。
1. 抽象观察者:
/**
* @author: wayne
* @desc: 抽象观察者
* @date: 2017/12/27 14:31
* @version: 1.0
*/
public interface Observer {
/**
* 更新观察者状态
* @param message
*/
public void update(String message);
}
2. 具体观察者,微信用户
/**
* @author: wayne
* @desc: 具体观察者-微信用户
* @date: 2017/12/27 14:34
* @version: 1.0
*/
public class User implements Observer{
/**
* 微信用户名
*/
private String name;
public User(String name) {
this.name = name;
}
@Override
public void update(String message) {
System.out.println("用户名:"+name+"--"+message);
}
}
3. 抽象被观察者。
/**
* @author: wayne
* @desc: 抽象主题接口
* @date: 2017/12/27 14:15
* @version: 1.0
*/
public interface Subject {
/**
* 添加观察者
* @param observer
*/
public void addObserver(Observer observer);
/**
* 删除观察者
* @param observer
*/
public void deleteObserver(Observer observer);
/**
* 通知订阅者更新消息
* @param message
*/
public void notifyAll(String message);
}
4.具体被观察者,微信公众号
/**
* @author: wayne
* @desc: 具体被观察者--微信公众号
* @date: 2017/12/27 14:41
* @version: 1.0
*/
public class Weixin implements Subject{
/**
* 存储观察者
*/
private List<Observer> userList = new ArrayList<Observer>();
public List<Observer> getUserList() {
return userList;
}
public void setUserList(List<Observer> userList) {
this.userList = userList;
}
@Override
public void addObserver(Observer observer) {
userList.add(observer);
}
@Override
public void deleteObserver(Observer observer) {
userList.remove(observer);
}
@Override
public void notifyAll(String message) {
for(Observer observer: userList){
observer.update(message);
}
}
}
测试结果:
/**
* @author: wayne
* @desc: 测试观察者模式
* @date: 2017/12/27 14:47
* @version: 1.0
*/
public class TestObserver {
public static void main(String[] args) {
Weixin weixin = new Weixin();
User user1 = new User("张三");
User user2 = new User("李四");
User user3 = new User("王五");
User user4 = new User("麻子");
weixin.addObserver(user1);
weixin.addObserver(user2);
weixin.addObserver(user3);
weixin.addObserver(user4);
System.out.println("用户订阅完成!");
weixin.notifyAll("有消息来了,收到没?");
}
}
用户订阅完成!
用户名:张三--有消息来了,收到没?
用户名:李四--有消息来了,收到没?
用户名:王五--有消息来了,收到没?
用户名:麻子--有消息来了,收到没?
怎么说呢,写下来的感觉就是类似生产者消费者模型,但是又不像,因为啥呢?因为观察者模式里面只有一个生产者,但是生产者消费者模型并不是,这是个人看得见的理解。
看下JDK其实已经提供了观察者模式的类和接口,在util下。
1. 观察者接口,也是只有一个update接口,在状态变更时能够改变观察者的状态。
package java.util;
/**
* A class can implement the <code>Observer</code> interface when it
* wants to be informed of changes in observable objects.
*
* @author Chris Warth
* @see java.util.Observable
* @since JDK1.0
*/
public interface Observer {
/**
* This method is called whenever the observed object is changed. An
* application calls an <tt>Observable</tt> object's
* <code>notifyObservers</code> method to have all the object's
* observers notified of the change.
*
* @param o the observable object.
* @param arg an argument passed to the <code>notifyObservers</code>
* method.
*/
void update(Observable o, Object arg);
}
2. 被观察者接口,简单复制一下,底层使用的Vector,里面的方法都是线程安全的方法。
public class Observable {
private boolean changed = false;
private Vector obs;
/** Construct an Observable with zero Observers. */
public Observable() {
obs = new Vector();
}
/**
* Adds an observer to the set of observers for this object, provided
* that it is not the same as some observer already in the set.
* The order in which notifications will be delivered to multiple
* observers is not specified. See the class comment.
*
* @param o an observer to be added.
* @throws NullPointerException if the parameter o is null.
*/
public synchronized void addObserver(Observer o) {
if (o == null)
throw new NullPointerException();
if (!obs.contains(o)) {
obs.addElement(o);
}
}