观察者模式

出版者(主题:Subject)+订阅者(观察者:Observer)=观察者模式

定义

观察者模式定义了对象之间的一对多依赖,这样依赖,当一个对象改变状态时,它的所有依赖者都会收到通知并自动更新

原则

  • 为了交互对象之间的松耦合设计而努力,松耦合设计更有弹性更能应对变化

代表人物 - > MVC

a.定义观察者模式

类图.png

b.自己实现观察者模式

/**
 * Created by xjw on 2017/11/9 16:53
 * Email 1521975316@qq.com
 */

public class Test {

    public interface Display {
        void display();
    }

    public interface Observer {
        void update(int a, int b, int c);
    }

    public interface Subject {
        void addObserver(Observer observer);

        void removeObserver(Observer observer);

        void notifiObserver();
    }

    static class WeekDate implements Subject {

        private List<Observer> observers;

        private int a;
        private int b;
        private int c;

        public WeekDate() {
            this.observers = new ArrayList<>();
        }

        @Override
        public void addObserver(Observer observer) {
            observers.add(observer);
        }

        @Override
        public void removeObserver(Observer observer) {
            int i = observers.indexOf(observer);
            if (i >= 0) {
                observers.remove(i);
            }
        }

        @Override
        public void notifiObserver() {
            for (int i = 0; i < observers.size(); i++) {
                observers.get(i).update(a, b, c);
            }
        }

        public void setData(int a, int b, int c) {
            this.a = a;
            this.b = b;
            this.c = c;
            notifiObserver();
        }

    }

    static class AObserver implements Observer, Display {

        private int a;
        private int b;
        private int c;

        public AObserver(Subject subject) {
            subject.addObserver(this);
        }

        @Override
        public void update(int a, int b, int c) {
            this.a = a;
            this.b = b;
            this.c = c;
            display();
        }

        @Override
        public void display() {
            System.out.println("a:" + a + ";b:" + b + ";c:" + c);
        }
    }

    public static void main(String[] args) {

        WeekDate subject = new WeekDate();
        AObserver observer = new AObserver(subject);

        subject.setData(1, 2, 3);
        subject.setData(4, 5, 6);

        subject.removeObserver(observer);

        subject.setData(7, 8, 9);

    }

}

c.Java提供的观察者模式

  • 观察者接口(java.util.Observer)
  • 可被观察者类(java.util.Observable),相当于主题Subject

使用

public class Test4Java {

    interface MDisplay {
        void display();
    }

    //可观察者
    static class MSubject extends Observable {

        private int a;

        public void setData(int data) {
            this.a = data;
            setChanged();//标记状态已经改变的事实
            notifyObservers();//送出通知
//            notifyObservers(a);
        }

        public int getData() {
            return a;
        }

    }

    //将对象变成观察者 implements java.util.Observer
    static class MObserver implements java.util.Observer, MDisplay {

        private int a;

        public MObserver(Observable observable) {
            observable.addObserver(this);
        }

        @Override
        public void update(Observable o, Object arg) {
            if (o instanceof MSubject) {
                MSubject subject = (MSubject) o;
                this.a = subject.getData();
                display();
            }
        }

        @Override
        public void display() {
            System.out.println("a:" + a);
        }
    }

    public static void main(String[] args) {

        MSubject subject = new MSubject();
        MObserver o = new MObserver(subject);
        subject.setData(1);
        subject.setData(2);
        subject.deleteObserver(o);
        subject.setData(3);

    }
}

setChanged()方法内幕

setChanged(){ 
    changed = true
};
notifyObservers(Object arg){
    if(changed){
         for every observer on the list{ call update(this,arg) }
    }
    changed = false;
}
notifyObservers(){ 
    notifyObservers(null)
}
clearChanged(){
    changed = false;
}

缺点

  • Observable 是一个类,Java不支持多继承
  • Observable 将关键方法保护起来.意味着:除非你继承自Observable,否则无法创建实例并组合到你自己的对象中来.这个设计违反的"多用组合少用继承"的设计原则

推荐阅读更多精彩内容