在对象关系间定义了一个一对多的依赖关系,当一个对象改变状态时,以便于它的依赖对象能够被自动化地被告知和更新。观察者模式是属于行为型模式之一。一个对象(object)发生状态改变而做出相应的反应,这个成为Observer;相对应的,被观察者就称之为Subject。
Java提供了通过 java.util.Observable 类和 java.util.Observer接口实现观察者模式的构建平台。然而,它并没有被广泛使用,因为这个实现太简单,并且没有这个必要。
Java消息服务(JMS)使用了观察者模式,伴随着中介者模式,允许应用程序订阅和发布数据到其它的应用程序中。Web开发中,流行的MVC(Model-View-Controller)框架也使用观察模式,模型(model)就是一个Subject,视图(Views)就是观察者。它通过注册到模型上,模型上任何变动都会通知视图。
实现一个实例,UML视图如下所示:
对于这个例子,我们将实现一个简单的主题,观察者注册到这个主题上。无论何时什么信息发送到这个主题上,所有它的注册者将收到这个信息,它们能够根据这个信息做相应的操作。有点像微薄信息的推送模式,认真理解了一定会发现其中的相似之处。
主体类Subject
public interface Subject {
//methods to register and unregister observers
public void register(Observer obj);
public void unregister(Observer obj);
//method to notify observers of change
public void notifyObservers();
//method to get updates from subject
public Object getUpdate(Observer obj);
}
观察者类
public interface Observer {
//method to update the observer, used by subject
public void update();
//attach with subject to observe
public void setSubject(Subject sub);
}
我的主题信息类。
public class MyTopic implements Subject {
private List<Observer> observers;
private String message;
private boolean changed;
private final Object MUTEX= new Object();
public MyTopic(){
this.observers=new ArrayList<>();
}
@Override
public void register(Observer obj) {
if(obj == null) throw new NullPointerException("Null Observer");
if(!observers.contains(obj)) observers.add(obj);
}
@Override
public void unregister(Observer obj) {
observers.remove(obj);
}
@Override
public void notifyObservers() {
List<Observer> observersLocal = null;
//synchronization is used to make sure any observer registered after message is received is not notified
synchronized (MUTEX) {
if (!changed)
return;
observersLocal = new ArrayList<>(this.observers);
this.changed=false;
}
for (Observer obj : observersLocal) {
obj.update();
}
}
@Override
public Object getUpdate(Observer obj) {
return this.message;
}
//method to post message to the topic
public void postMessage(String msg){
System.out.println("Message Posted to Topic:"+msg);
this.message=msg;
this.changed=true;
notifyObservers();
}
}
定义观察者的实现类,它将绑定到这个Subject上。
public class MyTopicSubscriber implements Observer {
private String name;
private Subject topic;
public MyTopicSubscriber(String nm){
this.name=nm;
}
@Override
public void update() {
String msg = (String) topic.getUpdate(this);
if(msg == null){
System.out.println(name+":: No new message");
}else
System.out.println(name+":: Consuming message::"+msg);
}
@Override
public void setSubject(Subject sub) {
this.topic=sub;
}
}
测试类,实现如下:
public class ObserverPatternTest {
public static void main(String[] args) {
//create subject
MyTopic topic = new MyTopic();
//create observers
Observer obj1 = new MyTopicSubscriber("Obj1");
Observer obj2 = new MyTopicSubscriber("Obj2");
Observer obj3 = new MyTopicSubscriber("Obj3");
//register observers to the subject
topic.register(obj1);
topic.register(obj2);
topic.register(obj3);
//attach observer to subject
obj1.setSubject(topic);
obj2.setSubject(topic);
obj3.setSubject(topic);
//check if any update is available
obj1.update();
//now send message to subject
topic.postMessage("New Message");
}
}
输出结果:
Obj1:: No new message
Message Posted to Topic:New Message
Obj1:: Consuming message::New Message
Obj2:: Consuming message::New Message
Obj3:: Consuming message::New Message