UP | HOME

观察者模式

Table of Contents

当一个对象变化时,其它依赖该对象的对象都会收到通知,并且随着变化,对象之间是一种一对多的关系!

UML

observer.png

Java

  • 定义观察者接口Observer,当被观察的对象发生变化时,会调用这个接口的update方法:
    public interface Observer {
        void update();
    }
    
  • 实现2个具体的观察者类:
    public class Observer1 implements Observer {
        @Override
        public void update() {
            System.out.println("observer1 has received!");
        }
    }
    
public class Observer1 implements Observer {
    @Override
    public void update() {
        System.out.println("observer1 has received!");
    }
}
  • 定义被观察者的接口Subject:
    public interface Subject {
        /*增加观察者*/
        public void add(Observer observer);
    
        /*删除观察者*/
        public void del(Observer observer);
    
        /*通知所有的观察者*/
        public void notifyObservers();
    
        /*自身的操作*/
        public void operation();
    }
    
  • 实现对观察者Observer的基本操作:
    public abstract class AbstractSubject implements Subject {
        private Vector<Observer> observers = new Vector<>();
    
        @Override
        public void add(Observer observer) {
            observers.add(observer);
        }
    
        @Override
        public void del(Observer observer) {
            observers.remove(observer);
        }
    
        @Override
        public void notifyObservers() {
            for (Observer observer : observers)
                observer.update();
        }
    }
    
  • 实现被观察者真正的业务逻辑:
    public class MySubject extends AbstractSubject {
        @Override
        public void operation() {
            System.out.println("update self!");
            notifyObservers();
        }
    }
    
  • 测试类:
    public class ObserverTest {
        public static void main(String[] args) {
            Subject sub = new MySubject();
            sub.add(new Observer1());
            sub.add(new Observer2());
    
            sub.operation();
        }
    }
    
  • 测试结果:
    update self!
    observer1 has received!
    observer2 has received!
    

CLOS

  • 定义观察者的通用方法:
    (defclass observer () ())
    (defclass observer1 (observer) ())
    (defclass observer2 (observer) ())
    
    (defmethod update ((o observer1))
      (format t "observer1 has received! ~C" #\linefeed))
    (defmethod update ((o observer2))
      (format t "observer2 has received! ~C" #\linefeed))
    
  • 使用辅助方法:after实现更新:
    (defclass subject ()
      ((observers :accessor subject-observers
                  :initarg :observers
                  :initform '())))
    
    (defmethod operation ((s subject))
      (format t "update self! ~C" #\linefeed))
    ;;依次调用观察者列表中每个元素的update方法
    (defmethod operation :after ((s subject))
      (mapc #'update (subject-observers s)))
    
  • 测试:
    (setf s (make-instance 'subject
                           :observers (list (make-instance 'observer1) (make-instance 'observer2))))
    
    (operation s)
    ;; => update self! 
    ;;    observer1 has received! 
    ;;    observer2 has received!
    

Next:迭代模式

Previous:模板模式

Home:目录