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;
}
}
网友评论