观察者模式

2017-05-29  本文已影响28人  冉桓彬

1、观察者模式介绍:

观察者模式是一个使用率非常高的模式, 它最常用的地方就是GUI系统、订阅--发布系统, 因为这个模式的一个重要作用就是解耦, 将被观察者和观察者解耦, 使得它们之间的依赖性更小, 甚至做到毫无依赖, 以GUI系统来说, 应用的UI更具有易变性, 尤其是前期随着业务的改变或者产品的需求修改, 应用界面也会经常性变化, 但是业务逻辑基本变化不大, 此时, GUI系统需要一套机制来应对这种情况, 使得UI层与具体的业务逻辑解耦, 观察者模式此时就派上用场了;

2、观察者模式的定义:

定义对象间一种一对多的依赖关系, 使得每当一个对象改变状态, 则所有依赖于它的序都会得到通知并被自动更新.

3、观察者模式的使用场景:

(1) 关联行为场景, 需要注意的是, 关联行为是可拆分的, 而不是"组合"关系;
  (2) 事件多级触发场景;
  (3) 跨系统的消息交换场景, 如消息队列, 事件总线的处理机制;

4、优缺点:

优点:

(1) 观察者和被观察者之间是抽象耦合, 应对业务变化;
  (2) 增强系统灵活性、可扩展性;

缺点:

在应用观察者模式时需要考虑一下开发效率和运行效率问题, 程序中包括一个被观察者、多个观察者、开发和调试等内容会比较复杂, 而且在Java中消息的通知默认是顺序执行, 一个观察者卡顿, 会影响整体的执行效率, 在这种情况下, 一般考虑采用异步的方式;

5、示例代码:

public class Coder implements Observer {
    public String mName;

    public Coder(String name) {
        mName = name;
    }

    @Override
    public void update(Observable o, Object arg) {
        System.out.println("Hi, " + mName + ", DevTechFrontier更新,内容:" + arg);
    }

    @Override
    public String toString() {
        return "码农:" + mName;
    }
}

public class DevTechFrontier extends Observable {
    public void postNewPublication(String content) {
        setChanged();
        notifyObservers(content);
    }
}

public class ObjTest {
    public static void main(String[] args) {
        DevTechFrontier d = new DevTechFrontier();
        Coder mrsimple = new Coder("mr.simple");
        Coder coder1 = new Coder("coder-1");
        Coder coder2 = new Coder("coder-2");
        Coder coder3 = new Coder("coder-3");
        d.addObserver(mrsimple);
        d.addObserver(coder1);
        d.addObserver(coder2);
        d.addObserver(coder3);
        d.postNewPublication("ObjTest");
        Vector v = new Vector();
        v.clone();
    }
}

6、关键类分析:

1. Observer:
public interface Observer {
    void update(Observable o, Object obj);
}
2. Observable:
public class Observable {
    private boolean changed = false;
    private Vector<Observer> obs;
    public Observable() {
        obs = new Vector<>();
    }
    protected synchronized void setChanged() {
        changed = true;
    }
    public void notifyObservers(Object arg) {
        Object[] arrLocal;
        synchronized (this) {
            if (!changed)
                return;
            arrLocal = obs.toArray();
            clearChanged();
        }
        for (int i = arrLocal.length-1; i>=0; i--)
            ((Observer)arrLocal[i]).update(this, arg);
    }
    protected synchronized void clearChanged() {
        changed = false;
    }
}
上一篇下一篇

猜你喜欢

热点阅读