观察者模式
概述
如果一个对象A的行为依赖另一个对象B的状态,我们可以有两种实现方式:
一种是对象A轮询对象B的状态,根据轮询结果决定自己的行为;另一种是对象B在自身状态发生改变时,主动通知对象A。
不难看出,第二种凡是会比第一种方式效率高,观察者模式即采用第二种方式,观察者模式可以用于事件监听、通知发布等场合。可以确保观察者在不使用轮询监控的情况下,及时收到相关消息和事件。
类图
主题接口依赖观察者接口,因为要在主题中注册观察者(观察者订阅主题)
jdk已经提供了观察者模式
实例
Observer
1 /** 2 * 观察者接口 3 * 4 * @author zhya 5 * @date 2018/9/14 6 **/ 7 public interface IObserver { 8 /** 9 * 通知 10 * 11 * @param event 12 */ 13 void update(Event event); 14 }
Concrete Observer
1 /** 2 * 实际观察者 3 * 4 * @author zhangyang 5 * @date 2018/9/14 6 **/ 7 public class Observer implements IObserver { 8 private String name; 9 10 public Observer(String name) { 11 this.name = name; 12 } 13 14 /** 15 * 通知 16 * 17 * @param event 18 */ 19 @Override 20 public void update(Event event) { 21 System.out.println(new StringBuffer("observer ").append(this.name).append(" received notification : ").append(event.getMsg())); 22 } 23 }
Subject
1 /** 2 * 主题/被观察者接口 3 * 4 * @author zhangyang 5 * @date 2018/9/14 6 **/ 7 public interface ISubject { 8 /** 9 * 注册监听者 10 * 11 * @param observer 12 */ 13 void attach(IObserver observer); 14 15 /** 16 * 注销监听者 17 * 18 * @param observer 19 */ 20 void deattach(IObserver observer); 21 22 /** 23 * 变更通知 24 * 25 * @param event 26 */ 27 void inform(Event event); 28 }
Concrete Subject
1 import java.util.List; 2 import java.util.Vector; 3 4 /** 5 * 实际主题/被观察者 6 * 7 * @author zhangyang 8 * @date 2018/9/14 9 **/ 10 public class Subject implements ISubject { 11 private final List<IObserver> observers = new Vector<>(); 12 13 /** 14 * 注册监听者 15 * 16 * @param observer 17 */ 18 @Override 19 public void attach(IObserver observer) { 20 if (!observers.contains(observer)) { 21 observers.add(observer); 22 } 23 } 24 25 /** 26 * 注销监听者 27 * 28 * @param observer 29 */ 30 @Override 31 public void deattach(IObserver observer) { 32 observers.remove(observer); 33 } 34 35 /** 36 * 变更通知 37 * 38 * @param event 39 */ 40 @Override 41 public void inform(Event event) { 42 System.err.println("subject has new event : " + event.toString()); 43 observers.forEach(observer -> observer.update(event)); 44 } 45 }
Main测试类
1 /** 2 * 测试类 3 * 4 * @author zhya 5 * @date 2018/9/14 6 **/ 7 public class Main { 8 public static void main(String[] args) { 9 // 监听者 10 IObserver observer1 = new Observer("observer1"); 11 IObserver observer2 = new Observer("observer2"); 12 13 // 主题 14 ISubject subject = new Subject(); 15 16 // 注册监听 17 subject.attach(observer1); 18 subject.attach(observer2); 19 20 // 主题状态变更 21 Event event = new Event("ding ding"); 22 subject.inform(event); 23 System.out.println("------------------------------------------"); 24 25 // 注销监听 26 subject.deattach(observer1); 27 28 // 主题状态变更 29 event = new Event("dang dang"); 30 subject.inform(event); 31 32 } 33 }
执行结果