java - 观察者模式

观察者模式

观察者模式的定义

定义对象之间一种一对多的关系。当一个对象的状态发生改变的时候,所有依赖于它的对象都得到通知并被自动更新。

观察者模式的结构和说明

观察者模式的结构图如图所示
  • Subject: 目标对象,通常具有以下功能

    • 一个目标可以被多个观察者观察
    • 目标提供观察者注册和退订的维护
    • 当目标的状态发生变化的时候,目标负责通知所有注册的,有效的观察者。
  • Observer: 定义观察者的借口,提供目标通知时对应的更新方法,这个更新方法进行相应的业务处理,可以在这个方法里面回调目标对象,翼获取目标对象的数据。

  • ConcreteSubject: 具体目标实现对象,用来维护目标状态,当目标对象的状态发生改变的时候,通知所注册的,有效的观察者,让观察者执行相应的处理。
  • ConcreteObserver: 观察者的具体实现对象,用来接受目标的通知,并进行相应的后续处理,比如更新自身的状态以保持和目标的相应状态一致。

观察者模式示例代码

(1) 目标对象的定义,实例代码:
public class Subject{

    /**
    *用来保存注册的观察者对象
    */
    private List<Observer> observers = new ArrayList<Observer>();

    /**
    *注册观察者对象
    */
    public void attach(Observer observer){
        observers.add(observer);
    }

    /**
    *删除观察者对象
    */
    public void detach(Observer observer){
        observers.remove(observer);
    }

    /**
    *通知所有注册的观察者对象
    */
    protected void notifyObservers(){
        for(Observer observer : observers){
            observer.update(this);
        }
    }
}
(2)具体目标对象。示例代码:
/**
* 具体的目标对象,负责把有关状态存入到相应的观察者对象
* 并在自己状态发生改变的时候,通知各个观察者
*/
public class ConcreteSubject extends Subject{
    /**
    * 示意,目标对象的状态
    */
    private String subjectState'
    public String getSubjectState(){
        return subjectState;
    }

    public void setSubjectState(String subjectState){
        this.subjectState = subjectState;
        //状态发生了改变,通知哥哥观察者
        this.notifyObservers();
    }
}
(3)观察者的接口定义,示例代码:
    /**
    *观察者接口,定义一个更新的接口给那些在目标发生改变的时候被                    *通知的对象
    */
    public interface Observer{
        public void update(Subject subject);
    }
(4)观察者的具体实现,示例代码:
/**
*具体观察者对象,实现更新的方法,使自身的状态和目标的状态保持一
*致
*/
public class ConcreteObserver implements Observer{
    private String observerState;

    public void update(Subject subject){
        //具体更新的实现
        //这里可能需要更新观察者的状态,使其与目标状态一致
        observerState = ((ConcreteSubject)subject).getSubjectState();

    }
}

认识观察者模式

1.目标和观察者之间的关系
按照模式的定义,目标和观察者之间是典型的一对多的关系。
但是要注意,如果观察者只有一个也是可以的,这样就变相的实现了目标和观察者之间一对一的关系,这也使得在处理一个对象的状态变化影响到另一个对象的时候,也可以考虑使用观察者模式。
同样,一个观察者也可以同时观察多个目标,如果观察者为多个目标定义的更新方法都叫update的话会有问题,因为要接收多个目标的通知,如果一个update则需要在方法内部进行区分,一般观察者应该为不用的观察者定义不同的回调方法,这样实现最好。
2.单向依赖
在观察者模式中,观察者和目标是单向依赖的,只有观察者依赖于目标,而目标不会依赖于观察者。
它们之间的联系的主动权掌握在目标手中,只有目标知道什么时候需要通知观察者。在整个过程中,观察者始终是被动的,被动地等待目标的通知,等待目标传值给它。
3.具体的实现说明
  • 具体的目标实现对象要能维护观察者的注册信息,最简单的实现方案就如同前面的例子那样,采用一个集合来保存观察者的注册信息。
  • 具体的目标实现对象需要维护引起通知的状态,一般情况下是目标自身的状态。变形使用的情况下,也可以是别的对象的状态。
  • 具体的观察者实现对象需要能接受目标的通知,能够接收目标传递的数据,或者能主动的去获取目标的数据,并进行后续的处理。
  • 如果是一个观察者观察多个目标,那么在观察者的更新方法里面,需要去判断是来自哪一个目标的通知。一种简单的解决方案就是拓展update方法,比如在方法中多传递一个参数进行区分,要么直接定义多个回调方法。
4.触发通知的时机
在实现观察者模式的时候,一定要注意触发通知的时机,一般情况下,是在完成了状态的维护后触发,因为通知会传递数据,不能够先通知后改数据,这很容易出问题,会导致观察者和目标对象的状态不一致。

观察者模式的本质

观察者模式的本质:触发联动
当修改目标对象的状态的时候,就会触发相应的通知,然后会循环调用所有注册的观察者对象的相应方法,其实就是相当于联动调用这些观察者的方法。
而且这个联动还是动态的,可以通过注册和取消注册来控制观察者,因而可以在程序运行期间,通过动态的控制观察者,来变相的实现添加和删除某些功能处理,这些功能就是观察者在update的时候执行的功能。
同时目标对象和观察者对象的解耦,又保证了无论观察者发生怎样的变化,目标对象总是能够正确地联动过来。

相关模式

  • 观察者模式和状态模式
观察者模式和状态模式之间有相似之处。
观察者模式是当目标状态发生变化的时候,触发并通知观察者,让观察者去执行相应的操作,而状态模式是根据不同的状态,选择不同的实现,这个实现类的主要功能就是针对状态相应地操作,它不像观察者,观察者本身还有很多其他的功能,接受通知并执行相应的处理只是观察者的部分功能。
当然观察者模式和状态模式是可以结合使用的。观察者模式的重心在触动,但是到底决定哪些观察者会被联动,这时就可以采用状态模式来实现了,也可以采用策略模式来进行需要的联动的观察者。
  • 5
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值