当前位置:   article > 正文

观察者模式(Observer)

oberservalbe

一:基本概念

1.什么是观察者模式

  • Observer模式是行为模式之一,它的作用是当一个对象的状态发生变化时,能够自动通知其他关联对象,自动刷新对象状态。
  • Observer模式提供给关联对象一种同步通信的手段,使某个对象与依赖它的其他对象之间保持状态同步。

2.观察者模式的UML结构

 

3.观察者模式的角色和职责

  • Subject(被观察者)    被观察的对象。当需要被观察的状态发生变化时,需要通知队列中所有观察者对象。Subject需要维持(添加,删除,通知)一个观察者对象的队列列表。
  • ConcreteSubject    被观察者的具体实现。包含一些基本的属性状态及其他操作。
  • Observer(观察者)    接口或抽象类。当Subject的状态发生变化时,Observer对象将通过一个callback函数得到通知。
  • ConcreteObserver    观察者的具体实现。得到通知后将完成一些具体的业务逻辑处理。

4.观察者模式的典型应用

  • Observer模式的典型应用
    • 侦听事件驱动程序设计中的外部事件
    • 侦听/监视某个对象的状态变化
    • 发布者/订阅者(publisher/subscriber)模型中,当一个外部事件(新的产品,消息的出现等等)被触发时,通知邮件列表中的订阅者

 

二:具体例子

1.功能需求描述:发布一条新闻的时候,观察者可以观察到。

2.具体实现:

2.1.效果:

  

2.2.项目结构

  • Article.java-文章bean
  • MyObservable.java-被观察者要实现的基类
  • MyObserver.java-观察者要实现的接口
  • NewsMainClass.java-启动方法
  • ObserverNews.java-实现了观察者接口的类
  • ObserverNews1.java-实现了观察者接口的类
  • PublisherArticle.java-实现了被观察者的类

  

2.3.运行流程

2.3.1.NewsMainClass.java类主要将,观察者对象注入到被观察者对象中。

  1. package com.witwicky.myobserver;
  2. public class NewsMainClass {
  3. public static void main(String[] args) {
  4. Article article = new Article("title1", "content1");
  5. PublisherArticle pa = new PublisherArticle();
  6. ObserverNews obn = new ObserverNews();
  7. ObserverNews1 obn1 = new ObserverNews1();
  8. pa.addOberserver(obn);
  9. pa.addOberserver(obn1);
  10. pa.removeOberserver(obn1);
  11. // pa.removeAll(); //可以使用
  12. pa.publisherArt(article);
  13. }
  14. }

 

2.3.2.Article.java-文章bean

  1. package com.witwicky.myobserver;
  2. public class Article {
  3. private String title;
  4. private String content;
  5. public Article(String title, String content) {
  6. this.title = title;
  7. this.content = content;
  8. }
  9. public String getTitle() {
  10. return title;
  11. }
  12. public void setTitle(String title) {
  13. this.title = title;
  14. }
  15. public String getContent() {
  16. return content;
  17. }
  18. public void setContent(String content) {
  19. this.content = content;
  20. }
  21. @Override
  22. public String toString() {
  23. return "Article [title=" + title + ", content=" + content + "]";
  24. }
  25. }

 

2.3.3.MyObservable.java-被观察者要实现的基类

自己实现:

  1. package com.witwicky.myobserver;
  2. import java.util.Vector;
  3. public class MyObservable {
  4. private Vector<MyObserver> observerList = new Vector<>();
  5. public void notifyObservers() {
  6. notifyObservers(null);
  7. }
  8. public void notifyObservers(Object object) {
  9. for (MyObserver myObserver : observerList) {
  10. myObserver.update(myObserver, object);
  11. }
  12. }
  13. public void addOberserver(MyObserver observer) {
  14. if(!observerList.contains(observer)) {
  15. observerList.addElement(observer);
  16. }
  17. }
  18. public void removeOberserver(MyObserver observer) {
  19. observerList.remove(observer);
  20. }
  21. public void removeAll() {
  22. observerList.removeAllElements();
  23. }
  24. public Integer obsCount() {
  25. return observerList.size();
  26. }
  27. }

 JDK中官方实现:

  1. /*
  2. * Copyright (c) 1994, 2012, Oracle and/or its affiliates. All rights reserved.
  3. * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
  4. */
  5. package java.util;
  6. /**
  7. * This class represents an observable object, or "data"
  8. * in the model-view paradigm. It can be subclassed to represent an
  9. * object that the application wants to have observed.
  10. * <p>
  11. * An observable object can have one or more observers. An observer
  12. * may be any object that implements interface <tt>Observer</tt>. After an
  13. * observable instance changes, an application calling the
  14. * <code>Observable</code>'s <code>notifyObservers</code> method
  15. * causes all of its observers to be notified of the change by a call
  16. * to their <code>update</code> method.
  17. * <p>
  18. * The order in which notifications will be delivered is unspecified.
  19. * The default implementation provided in the Observable class will
  20. * notify Observers in the order in which they registered interest, but
  21. * subclasses may change this order, use no guaranteed order, deliver
  22. * notifications on separate threads, or may guarantee that their
  23. * subclass follows this order, as they choose.
  24. * <p>
  25. * Note that this notification mechanism has nothing to do with threads
  26. * and is completely separate from the <tt>wait</tt> and <tt>notify</tt>
  27. * mechanism of class <tt>Object</tt>.
  28. * <p>
  29. * When an observable object is newly created, its set of observers is
  30. * empty. Two observers are considered the same if and only if the
  31. * <tt>equals</tt> method returns true for them.
  32. *
  33. * @author Chris Warth
  34. * @see java.util.Observable#notifyObservers()
  35. * @see java.util.Observable#notifyObservers(java.lang.Object)
  36. * @see java.util.Observer
  37. * @see java.util.Observer#update(java.util.Observable, java.lang.Object)
  38. * @since JDK1.0
  39. */
  40. public class Observable {
  41. private boolean changed = false;
  42. private Vector<Observer> obs;
  43. /** Construct an Observable with zero Observers. */
  44. public Observable() {
  45. obs = new Vector<>();
  46. }
  47. /**
  48. * Adds an observer to the set of observers for this object, provided
  49. * that it is not the same as some observer already in the set.
  50. * The order in which notifications will be delivered to multiple
  51. * observers is not specified. See the class comment.
  52. *
  53. * @param o an observer to be added.
  54. * @throws NullPointerException if the parameter o is null.
  55. */
  56. public synchronized void addObserver(Observer o) {
  57. if (o == null)
  58. throw new NullPointerException();
  59. if (!obs.contains(o)) {
  60. obs.addElement(o);
  61. }
  62. }
  63. /**
  64. * Deletes an observer from the set of observers of this object.
  65. * Passing <CODE>null</CODE> to this method will have no effect.
  66. * @param o the observer to be deleted.
  67. */
  68. public synchronized void deleteObserver(Observer o) {
  69. obs.removeElement(o);
  70. }
  71. /**
  72. * If this object has changed, as indicated by the
  73. * <code>hasChanged</code> method, then notify all of its observers
  74. * and then call the <code>clearChanged</code> method to
  75. * indicate that this object has no longer changed.
  76. * <p>
  77. * Each observer has its <code>update</code> method called with two
  78. * arguments: this observable object and <code>null</code>. In other
  79. * words, this method is equivalent to:
  80. * <blockquote><tt>
  81. * notifyObservers(null)</tt></blockquote>
  82. *
  83. * @see java.util.Observable#clearChanged()
  84. * @see java.util.Observable#hasChanged()
  85. * @see java.util.Observer#update(java.util.Observable, java.lang.Object)
  86. */
  87. public void notifyObservers() {
  88. notifyObservers(null);
  89. }
  90. /**
  91. * If this object has changed, as indicated by the
  92. * <code>hasChanged</code> method, then notify all of its observers
  93. * and then call the <code>clearChanged</code> method to indicate
  94. * that this object has no longer changed.
  95. * <p>
  96. * Each observer has its <code>update</code> method called with two
  97. * arguments: this observable object and the <code>arg</code> argument.
  98. *
  99. * @param arg any object.
  100. * @see java.util.Observable#clearChanged()
  101. * @see java.util.Observable#hasChanged()
  102. * @see java.util.Observer#update(java.util.Observable, java.lang.Object)
  103. */
  104. public void notifyObservers(Object arg) {
  105. /*
  106. * a temporary array buffer, used as a snapshot of the state of
  107. * current Observers.
  108. */
  109. Object[] arrLocal;
  110. synchronized (this) {
  111. /* We don't want the Observer doing callbacks into
  112. * arbitrary code while holding its own Monitor.
  113. * The code where we extract each Observable from
  114. * the Vector and store the state of the Observer
  115. * needs synchronization, but notifying observers
  116. * does not (should not). The worst result of any
  117. * potential race-condition here is that:
  118. * 1) a newly-added Observer will miss a
  119. * notification in progress
  120. * 2) a recently unregistered Observer will be
  121. * wrongly notified when it doesn't care
  122. */
  123. if (!changed)
  124. return;
  125. arrLocal = obs.toArray();
  126. clearChanged();
  127. }
  128. for (int i = arrLocal.length-1; i>=0; i--)
  129. ((Observer)arrLocal[i]).update(this, arg);
  130. }
  131. /**
  132. * Clears the observer list so that this object no longer has any observers.
  133. */
  134. public synchronized void deleteObservers() {
  135. obs.removeAllElements();
  136. }
  137. /**
  138. * Marks this <tt>Observable</tt> object as having been changed; the
  139. * <tt>hasChanged</tt> method will now return <tt>true</tt>.
  140. */
  141. protected synchronized void setChanged() {
  142. changed = true;
  143. }
  144. /**
  145. * Indicates that this object has no longer changed, or that it has
  146. * already notified all of its observers of its most recent change,
  147. * so that the <tt>hasChanged</tt> method will now return <tt>false</tt>.
  148. * This method is called automatically by the
  149. * <code>notifyObservers</code> methods.
  150. *
  151. * @see java.util.Observable#notifyObservers()
  152. * @see java.util.Observable#notifyObservers(java.lang.Object)
  153. */
  154. protected synchronized void clearChanged() {
  155. changed = false;
  156. }
  157. /**
  158. * Tests if this object has changed.
  159. *
  160. * @return <code>true</code> if and only if the <code>setChanged</code>
  161. * method has been called more recently than the
  162. * <code>clearChanged</code> method on this object;
  163. * <code>false</code> otherwise.
  164. * @see java.util.Observable#clearChanged()
  165. * @see java.util.Observable#setChanged()
  166. */
  167. public synchronized boolean hasChanged() {
  168. return changed;
  169. }
  170. /**
  171. * Returns the number of observers of this <tt>Observable</tt> object.
  172. *
  173. * @return the number of observers of this object.
  174. */
  175. public synchronized int countObservers() {
  176. return obs.size();
  177. }
  178. }

 

2.3.4.MyObserver.java-观察者要实现的接口

自己实现:

  1. package com.witwicky.myobserver;
  2. public interface MyObserver {
  3. public void update(MyObserver myobserver, Object object);
  4. }

JDK官方实现:

  1. /*
  2. * Copyright (c) 1994, 1998, Oracle and/or its affiliates. All rights reserved.
  3. * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
  4. */
  5. package java.util;
  6. /**
  7. * A class can implement the <code>Observer</code> interface when it
  8. * wants to be informed of changes in observable objects.
  9. *
  10. * @author Chris Warth
  11. * @see java.util.Observable
  12. * @since JDK1.0
  13. */
  14. public interface Observer {
  15. /**
  16. * This method is called whenever the observed object is changed. An
  17. * application calls an <tt>Observable</tt> object's
  18. * <code>notifyObservers</code> method to have all the object's
  19. * observers notified of the change.
  20. *
  21. * @param o the observable object.
  22. * @param arg an argument passed to the <code>notifyObservers</code>
  23. * method.
  24. */
  25. void update(Observable o, Object arg);
  26. }

 

2.3.5.ObserverNews.java-实现了观察者接口的类

  1. package com.witwicky.myobserver;
  2. public class ObserverNews implements MyObserver {
  3. @Override
  4. public void update(MyObserver myobserver, Object object) {
  5. System.out.println("观察者:观察到又发布了一条新闻,内容如下:"+object.toString());
  6. }
  7. }

 

2.3.6.ObserverNews1.java-实现了观察者接口的类

  1. package com.witwicky.myobserver;
  2. public class ObserverNews1 implements MyObserver {
  3. @Override
  4. public void update(MyObserver myobserver, Object object) {
  5. System.out.println("观察者1:观察到又发布了一条新闻,内容如下:"+object.toString());
  6. }
  7. }

 

2.3.7.PublisherArticle.java-实现了被观察者的类

  1. package com.witwicky.myobserver;
  2. public class PublisherArticle extends MyObservable {
  3. public void publisherArt(Article article) {
  4. System.out.println("发布者:发布了新文章:" + article.toString());
  5. this.notifyObservers(article);
  6. System.out.println(this.obsCount());
  7. }
  8. }

 

注:最关键的两个类是 MyObserver与MyObservalbe,自己实现代码更灵活一些,如果只是使用基本功能的话,官方JDK版本,更健壮。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Gausst松鼠会/article/detail/333658
推荐阅读
相关标签
  

闽ICP备14008679号