使用场景:
当一个对象的行为依赖于另一个对象的状态。
一般用于事件监听、通知发布等场合

应用场景:
swing框架中的JButton实现 [按钮点击,通知监听器]

源码实践

观察者

  1. package xin.rtime.design.observer;
  2. // 抽象的观察者
  3. public interface IObserver {
  4. public void update(String msg);
  5. }

被观察者

  1. package xin.rtime.design.observer;
  2. // 抽象的被观察者 [主题接口] --- 可以查看 java.util.Observable实现
  3. public interface ISubject {
  4. // 注册观察者
  5. public void registerObserver(IObserver o);
  6. // 删除观察者
  7. public void removeObserver(IObserver o);
  8. // 通知观察者
  9. public void notifyObserver();
  10. // 带参数的通知观察者
  11. void notifyObserver(String args);
  12. }

具体的观察者

  1. package xin.rtime.design.observer;
  2. import java.util.Vector;
  3. // 具体的被观察者对象
  4. public class ConcreteSubject implements ISubject{
  5. Vector<IObserver> observers = new Vector<IObserver>();
  6. @Override
  7. public void registerObserver(IObserver o) {
  8. observers.add(o);
  9. }
  10. @Override
  11. public void removeObserver(IObserver o) {
  12. observers.remove(o);
  13. }
  14. @Override
  15. public void notifyObserver() {
  16. notifyObserver(null);
  17. }
  18. @Override
  19. public void notifyObserver(String args) {
  20. for(IObserver iObserver : observers) {
  21. iObserver.update(args);
  22. }
  23. }
  24. }

具体的观察者

  1. package xin.rtime.design.observer;
  2. // 具体的观察者
  3. public class ConcreteObserver implements IObserver {
  4. @Override
  5. public void update(String msg) {
  6. System.out.println("update " + msg);
  7. }
  8. }

验证

  1. package xin.rtime.design;
  2. import java.util.Observable;
  3. f
  4. import xin.rtime.design.observer.ConcreteObserver;
  5. import xin.rtime.design.observer.ConcreteSubject;
  6. public class ObServerTest {
  7. public static void main(String[] args) {
  8. // 简易实现
  9. ConcreteSubject subject = new ConcreteSubject(); // 定义主题
  10. subject.registerObserver(new ConcreteObserver()); // 注册观察者
  11. ConcreteObserver observer2 = new ConcreteObserver();
  12. subject.registerObserver(observer2); // 注册观察者
  13. subject.notifyObserver(); // 发送通知
  14. subject.removeObserver(observer2); // 删除观察者
  15. subject.notifyObserver("test"); // 继续通知
  16. }
  17. }

观察者模式 - 图1

JDK原生实践

定义一个观察者:

  1. package xin.rtime.observable;
  2. public class MyObservable extends Observable {
  3. private int num;
  4. public int getNum() {
  5. return num;
  6. }
  7. public void setNum(int num) {
  8. this.num = num;
  9. setChanged(); // 变更状态
  10. notifyObservers(num); // 通知
  11. }
  12. }

验证:

  1. package xin.rtime.design;
  2. import java.util.Observable;
  3. import java.util.Observer;
  4. import xin.rtime.design.observable.MyObservable;
  5. public class ObServerTest {
  6. public static void main(String[] args) {
  7. // jdk 内置观察者api
  8. MyObservable observable = new MyObservable();
  9. Observer observer = new Observer() {
  10. @Override
  11. public void update(Observable o, Object arg) {
  12. System.out.println("udpate " + arg); // 接收通知
  13. }
  14. };
  15. observable.addObserver(observer);
  16. observable.setNum(123);
  17. }
  18. }

观察者模式 - 图2