前言:
之前项目有个模块需要实现被通知的作用,那是第一时间就想到了观察者,那个模块是对象间一对一的依赖关系,因此对当时找到的观察者一对多的例子进行了简化,在简化过程中发现观察者就是把一个对象放到另一处在通知时被调用,整体就是一个反向思考的过程。因此,本文也将有最完整的观察者一步步简化成最基本的调用代码进行讲解,不过在实际使用时,最好用观察者的模式来实现,它也起到了一定的解耦合的作用。
观察者模式定义:
观察者模式也叫发布订阅模式,对象间一种一对多的依赖关系,使得每当一个对象改变状态,则所有依赖于它的对象都会得到通知并自动更新。
观察者详细类图通用例子:
被观察者
public abstract class Subject{
// Vector是线程同步,ArrayList是线程异步,这里采用Vector
private Vector<Observer> obsVector = new Vector<Observer>();
public void addObserver(Observer o){
this.obsVector.add(o);
}
public void deleteObserver(Observer o){
this.obsVector.remove(o);
}
public void notifyObservers(){
for(Observer o:this.obsVector){
o.update();
}
}
}
具体被观察者
public class ConcreteSubject implements Subject{
//具体行为
public void doSomething(){
super.notifyObservers();
}
}
观察者
public interface Observer{
public void update();
}
具体观察者
public class ConcreteObserver implements Observer{
public void update(){
System.out.println(" 接收到信息,进行更新");
}
}
场景类
public class Client{
public static void main(String[] args){
ConcreteSubject subject = new ConcreteSubject();
Observer obs = new ConcreteObserver();
subject.addObserver(obs);
subject.doSomething();
}
}
简到不能再简之后:
简化后public class ConcreteSubject {
//具体业务
public void doSomething(ConcreteObserver obs){
obs.update();
}
}
public class ConcreteObserver{
//更新方法
public void update(){
System.out.println(" 接收到信息,进行更新");
}
}
public class Client{
public static void main(String[] args){
ConcreteSubject subject = new ConcreteSubject();
ConcreteObserver obs = new ConcreteObserver();
// obs的属性或行为发生变化是由subject导致的,那么就将obs传给subject,这样直接由subject来调用obs的函数,使其更新,从而避免了循环查询。
subject.doSomething(obs);
}
}
因此,观察者也是回调的一种扩展。
观察者的优点
抽象耦合:观察者和被观察者都非常容易扩展。
可用于建立触发机制,但在一个观察者模式中最多出现一个既是观察者又是被观察者的情况。
观察者的缺点
由于java中消息默认顺序执行,在多级触发情况下,需多加考虑其运行效率。
网友评论