比如在玩“极品飞车”这款游戏,每一个车手到达终点的时候,都会在其它车手的屏幕上显示:某某人以多少时间到达终点的提示,其实这就是一个典型的观察者模式的应用,观察者模式即是典型的双向一对多的应用场景下用一的一端来通知多的一端。
=============================================
从另一篇文章中摘录的比较到位的说明:
什么时候用观察者模式?
1)当一个抽象模型有两个方面, 其中一个方面依赖于另一方面。将这二者封装在独立的对象中以使它们可以各自独立地改变和复用。
2)当对一个对象的改变需要同时改变其它对象, 而不知道具体有多少对象有待改变。
3)当一个对象必须通知其它对象,而它又不能假定其它对象是谁。换言之, 你不希望这些对象是紧密耦合的。
其实观察者模式同前面讲过的桥梁、策略有着共同的使用环境:将变化独立封装起来,以达到最大的重用和解耦。观察者与后两者不同的地方在于,观察者模式中的目标和观察者的变化不是独立的,而是有着某些联系。
为什么要用观察者模式?
【观察者模式解释】
类型:行为模式
定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象的状态发生改变时,会通知所有的观察者对象,使它们能够自己更新自己。
【观察者模式UML图】
【观察者模式-JAVA代码实现】
新建抽象发布通知父类:
package carer_subject; import java.util.ArrayList; import java.util.List; import carer_observer.carer_observer; public interface carer_subject_parent { public void set_state(String state_string); public String get_state(); public void add_observer(carer_observer carer_observer_ref); public void sub_observer(carer_observer carer_observer_ref); public void notityAllCarer(); } |
新建发布通知实现类:
package carer_subject; import java.util.ArrayList; import java.util.List; import carer_observer.carer_observer; public class carer_subject_sub implements carer_subject_parent { List<carer_observer> list_observer = new ArrayList<carer_observer>(); private String state; public void set_state(String state_string) { this.state = state_string; } public String get_state() { return state; } public void add_observer(carer_observer carer_observer_ref) { list_observer.add(carer_observer_ref); } public void sub_observer(carer_observer carer_observer_ref) { list_observer.remove(carer_observer_ref); } public void notityAllCarer() { state = "到达终点"; for (int i = 0; i < list_observer.size(); i++) { list_observer.get(i).show_info(); } } } |
新建观察者接口:
package carer_observer; import carer_subject.carer_subject_parent; public interface carer_observer { public void show_info(); } |
package carer_observer; import carer_subject.carer_subject_parent; public class carer_observer_imple implements carer_observer { private carer_subject_parent carer_subject_parent_ref; public carer_subject_parent getCarer_subject_parent_ref() { return carer_subject_parent_ref; } public void setCarer_subject_parent_ref( carer_subject_parent carer_subject_parent_ref) { this.carer_subject_parent_ref = carer_subject_parent_ref; } public carer_observer_imple(carer_subject_parent carer_subject_parent_ref) { super(); this.carer_subject_parent_ref = carer_subject_parent_ref; } public void show_info() { System.out.println(carer_subject_parent_ref.get_state()); } } |
新建客户端运行类:
package run_main; import carer_observer.carer_observer_imple; import carer_subject.carer_subject_parent; import carer_subject.carer_subject_sub; public class run_main { public static void main(String[] args) { carer_subject_parent carer_subject_parent_ref = new carer_subject_sub(); carer_observer_imple carer_observer_imple_ref1 = new carer_observer_imple( carer_subject_parent_ref); carer_observer_imple carer_observer_imple_ref2 = new carer_observer_imple( carer_subject_parent_ref); carer_observer_imple carer_observer_imple_ref3 = new carer_observer_imple( carer_subject_parent_ref); carer_observer_imple carer_observer_imple_ref4 = new carer_observer_imple( carer_subject_parent_ref); carer_subject_parent_ref.add_observer(carer_observer_imple_ref1); carer_subject_parent_ref.add_observer(carer_observer_imple_ref2); carer_subject_parent_ref.add_observer(carer_observer_imple_ref3); carer_subject_parent_ref.add_observer(carer_observer_imple_ref4); carer_subject_parent_ref.sub_observer(carer_observer_imple_ref3); carer_subject_parent_ref.set_state("到达终点"); carer_subject_parent_ref.notityAllCarer(); } } |
程序运行结果如下:
到达终点 到达终点 到达终点 到达终点 |
以一对多的方式进行对一方状态的改变而去通知多方,观察者模式也叫发布/订阅模式,一方进行发布,而多方进行订阅,和生活中看报纸一样,你喜欢订城市晚报,就会发给你。