比如在玩“极品飞车”这款游戏,每一个车手到达终点的时候,都会在其它车手的屏幕上显示:某某人以多少时间到达终点的提示,其实这就是一个典型的观察者模式的应用,观察者模式即是典型的双向一对多的应用场景下用一的一端来通知多的一端。
=============================================
从另一篇文章中摘录的比较到位的说明:
什么时候用观察者模式?
<wbr>就是当一个对象改变时需要通知其它对象的时候。<br><wbr>GOF给出了以下使用观察者模式的情况:<br> 1)当一个抽象模型有两个方面, 其中一个方面依赖于另一方面。将这二者封装在独立的对象中以使它们可以各自独立地改变和复用。<br> 2)当对一个对象的改变需要同时改变其它对象, 而不知道具体有多少对象有待改变。<br> 3)当一个对象必须通知其它对象,而它又不能假定其它对象是谁。换言之, 你不希望这些对象是紧密耦合的。<br> 其实观察者模式同前面讲过的桥梁、策略有着共同的使用环境:将变化独立封装起来,以达到最大的重用和解耦。观察者与后两者不同的地方在于,观察者模式中的目标和观察者的变化不是独立的,而是有着某些联系。<br><span style="font-weight:bold">为什么要用观察者模式?</span><br><wbr>主要是能够很好的解耦.</wbr></wbr></wbr>
=============================================【观察者模式解释】
类型:行为模式
定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象的状态发生改变时,会通知所有的观察者对象,使它们能够自己更新自己。
【观察者模式UML图】
【观察者模式-JAVA代码实现】
新建抽象发布通知父类:
packagecarer_subject; importjava.util.ArrayList; importjava.util.List; importcarer_observer.carer_observer; publicinterfacecarer_subject_parent{ publicvoidset_state(Stringstate_string); publicStringget_state(); publicvoidadd_observer(carer_observercarer_observer_ref); publicvoidsub_observer(carer_observercarer_observer_ref); publicvoidnotityAllCarer(); } |
新建发布通知实现类:
packagecarer_subject; importjava.util.ArrayList; importjava.util.List; importcarer_observer.carer_observer; publicclasscarer_subject_subimplementscarer_subject_parent{ List<carer_observer>list_observer=newArrayList<carer_observer>(); privateStringstate; publicvoidset_state(Stringstate_string){ this.state=state_string; } publicStringget_state(){ returnstate; } publicvoidadd_observer(carer_observercarer_observer_ref){ list_observer.add(carer_observer_ref); } publicvoidsub_observer(carer_observercarer_observer_ref){ list_observer.remove(carer_observer_ref); } publicvoidnotityAllCarer(){ state="到达终点"; for(inti=0;i<list_observer.size();i++){ list_observer.get(i).show_info(); } } } |
新建观察者接口:
packagecarer_observer; importcarer_subject.carer_subject_parent; publicinterfacecarer_observer{ publicvoidshow_info(); } |
packagecarer_observer; importcarer_subject.carer_subject_parent; publicclasscarer_observer_impleimplementscarer_observer{ privatecarer_subject_parentcarer_subject_parent_ref; publiccarer_subject_parentgetCarer_subject_parent_ref(){ returncarer_subject_parent_ref; } publicvoidsetCarer_subject_parent_ref( carer_subject_parentcarer_subject_parent_ref){ this.carer_subject_parent_ref=carer_subject_parent_ref; } publiccarer_observer_imple(carer_subject_parentcarer_subject_parent_ref){ super(); this.carer_subject_parent_ref=carer_subject_parent_ref; } publicvoidshow_info(){ System.out.println(carer_subject_parent_ref.get_state()); } } |
新建客户端运行类:
packagerun_main; importcarer_observer.carer_observer_imple; importcarer_subject.carer_subject_parent; importcarer_subject.carer_subject_sub; publicclassrun_main{ publicstaticvoidmain(String[]args){ carer_subject_parentcarer_subject_parent_ref=newcarer_subject_sub(); carer_observer_implecarer_observer_imple_ref1=newcarer_observer_imple( carer_subject_parent_ref); carer_observer_implecarer_observer_imple_ref2=newcarer_observer_imple( carer_subject_parent_ref); carer_observer_implecarer_observer_imple_ref3=newcarer_observer_imple( carer_subject_parent_ref); carer_observer_implecarer_observer_imple_ref4=newcarer_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(); } } |
程序运行结果如下:
到达终点 到达终点 到达终点 到达终点 |
以一对多的方式进行对一方状态的改变而去通知多方,观察者模式也叫发布/订阅模式,一方进行发布,而多方进行订阅,和生活中看报纸一样,你喜欢订城市晚报,就会发给你。