观察者模式属于 行为模式之一,在软件工程中 广泛使用。接下来我用java 来实现 简单的观察者模式
观察者模式解决的问题:
项目中涉及到一个事物的改变 会同时使其他几个事物发生变化,或者说观察者 在监听被观察者的变化,一旦被观察者发生变化,立刻会出发观察者的变化。这种模式就为观察者模式。
观察者模式每个觉得该实现的方法跟属性:
通过上面的分析,就能感受到观察者模式应该是一种被观察者与观察者之间1对多的关系。被观察者应该有以下的属性跟方法:
简单的被观察者基类:
public abstract class Subject {
//添加观察者
public void attach(Observer o) {}
//移除观察者
public void detach(Observer o) {}
//当被观察者发生改变了时候 就要通知观察者的update方法(这块需要遍历每个观察者)
public void nodify(Observer o) {}
public abstract void do something();
}
观察者基类:
public abstract class Observer{
//仅仅实现update方法
public abstract void update();
}
现在把这2个被观察者与观察者的类以及实现的方法写出来 就会有条很清晰的观察者模式线路,如下:
实例化被观察者对象 如 subject1 然后通过attach方法 添加 观察者对象实例,
这时候 subject1 在运行dosomething这个方法时 调用notify 方法 通知所有的观察者实例。
这块要注意的是 保存所有观察者实例的容器 java 有很多 但是对于多线程安全来说vector 来最适合
所以这里我们使用vector 来做存放观察者对象实例的容器。
废话不多说 下面就是所有的java 观察者模式的代码了
Subject.java :
package Observer;
import java.util.Vector;
public abstract class Subject {
private Vector<Observer> vector = new Vector<Observer>();
public void attach(Observer o) {
vector.add(o);
}
public void detach(Observer o) {
vector.remove(o);
}
protected void nodify(){
for(Observer o: vector){
o.update();
}
}
public abstract void dosomething();
}
观察者基类 Observer.java :
package Observer;
public abstract class Observer {
public abstract void update();
}
继承Subject的类 Subject1.java :
package Observer;
public class Subject1 extends Subject{
@Override
public void dosomething() {
System.out.println("我要获取2个观察者的age");
this.nodify();
}
}
继承Observer的类 OneObserver.java :
package Observer;
public class OneObserver extends Observer{
@Override
public void update() {
System.out.println("观察者1的age为12");
}
}
最后客户端调用 Client.java :
package Observer;
public class Client {
public static void main(String[] args) {
Subject1 subject1 = new Subject1();
OneObserver observer = new OneObserver();
subject1.attach(observer);
subject1.attach(new TwoObserver());
subject1.dosomething();
}
}
运行主程序client,如下图所示:
代码地址在这里
观察者模式的优点 跟缺点 以及应用场景:
优点:
1、观察者和被观察者是抽象耦合的。 2、建立一套触发机制。
缺点:
1、如果一个被观察者对象有很多的直接和间接的观察者的话,将所有的观察者都通知到会花费很多时间。 2、如果在观察者和观察目标之间有循环依赖的话,观察目标会触发它们之间进行循环调用,可能导致系统崩溃。 3、观察者模式没有相应的机制让观察者知道所观察的目标对象是怎么发生变化的,而仅仅只是知道观察目标发生了变化。
应用场景:
1、有多个子类共有的方法,且逻辑相同。 2、重要的、复杂的方法,可以考虑作为模板方法。