定义对象间的一种一对多的依赖关系,当一个对象的状态发生变化时,所有依赖它的对象都得到通知并被自动更新。
define a one-to-many dependency between objects so that when one object changes state, all its dependents are notified and updated automatically.

观察者模式的结构中包括四个角色。
+ 主题(subject):主题是一个接口,该接口规定了具体主题需要实现的方法,比如,添加、删除观察者以及通知观察者更新数据的方法。
+ 具体主题(concrete subject):具体主题是实现主题接口类的一个实例,该实例包含有可以经常发生变化的数据。具体主题需使用一个集合,比如arraylist,存放观察者的引用,以便数据变化时通知具体观察者。
+ 观察者(observer):观察者一个接口或者抽象类,该接口规定了具体观察者用来更新数据的方法。
+ 具体观察者(concrete observer):具体观察者是实现观察者接口类的一个实例。具体观察者包含有可以存放具体主题引用的主题接口变量,以便具体观察者让具体主题将自己的引用添加到具体主题中,使自己成为它的观察者,或让这个具体主题将自己从具体主题的集合中删除,使自己不再是它的观察者。
推数据方式是指具体主题将变化后的数据全部交给具体观察者,即将变化后的数据传给具体观察者用于更新数据方法的参数。当具体主题认为具体观察者需要这些变化后的全部数据时往往采用推数据方式。
拉数据方式是指具体主题不将变化后的数据交给具体观察者,而是提供了获得这些数据的方法,具体观察者在得到通知后,可以调用具体主题提供的方法得到数据(观察者自己数据“拉”过来),但需要自己判断数据是否发生变化。当具体主题不知道具体观察者是需要这些变换后的数据时往往采用拉数据的方式。
一个具体观察者可以依赖于多个主题,当所有依赖的任何具体主题的数据发生变化时,该观察者都能得到通知。多主题所涉及的主要问题是观察者如何处理主题中变化后的数据,因为,不同的具体主题所包含有的数据结构可能很大不同。
在处理多主题时,主题应当采用拉数据方式,观察者接口可以将更新数据方法的参数类型设置为主题接口类型,比如update(subject subject),即具体主题数据放生变化时将自己的引用传递给具体的观察者,然后具体观察者让这个具体主题调用有关的方法返回该具体主题中的数据。
具体主题和具体观察者是松耦合关系。由于主题接口仅仅依赖于观察者接口,因此具体主题只是知道它的观察者是实现观察者接口的某个类的实例,但不需要知道具体哪个类。同样,由于观察者仅仅依赖于主题接口,因此具体观察者只是知道它依赖的主题是实现主题接口的某个类的实例,但不需要知道具体是哪一个类。
观察模式满足“开-闭原则”。主题接口仅仅依赖于观察者接口,这样,就可以让创建具体主题的类也仅仅是依赖于观察者接口,因此如果增加新的实现观察者接口的类,不必修改创建具体主题的类的代码。同样,创建具体观察者的类仅仅依赖于主题接口,如果增加新的实现主题接口的类,也不必修改创建具体观察者类的代码。
当一个对象的数据更新时需要通过其他对象,但这个对象又不希望和被通知的那些对象形成紧耦合。
当一个对象的数据更新时,这个对象需要让其他对象也各自更新自己的数据,但这个对象不知道具体有多少对象需要更新数据。
<a href="https://github.com/androidwolf">mygithub</a>