UNPKG

epubjs

Version:

Render ePub documents in the browser, across many devices

68 lines (67 loc) 9.13 kB
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"><head><title>Observers and Observables</title><link rel="stylesheet" href="core.css" type="text/css"/><meta name="generator" content="DocBook XSL Stylesheets V1.74.0"/></head><body><div class="sect1" title="Observers and Observables"><div class="titlepage"><div><div><h1 class="title"><a id="learnjava3-CHP-11-SECT-8"/>Observers and Observables</h1></div></div></div><p><a id="idx10632" class="indexterm"/> <a id="idx10663" class="indexterm"/>The <a id="I_indexterm11_id750326" class="indexterm"/><code class="literal">java.util.Observer</code> interface and <a id="I_indexterm11_id750337" class="indexterm"/><code class="literal">java.util.Observable</code> class are relatively small utilities, but they provide a glimpse of a fundamental design pattern in Java. Observers and observables are part of the MVC (Model-View-Controller) framework. It is an abstraction that lets a number of client objects (the <span class="emphasis"><em>observers</em></span>) be notified whenever a certain object or resource (the <span class="emphasis"><em>observable</em></span>) changes in some way. We will see this pattern used extensively in Java’s event mechanism, which is covered in Chapters <a class="xref" href="ch16.html" title="Chapter 16. Swing">16</a> through <a class="xref" href="ch19.html" title="Chapter 19. Layout Managers">19</a>. Although these classes are not often used directly, it’s worth looking at them in order to understand the pattern.</p><p>The <code class="literal">Observable</code> object has a method that an <code class="literal">Observer</code> calls to register its interest. When a change happens, the <code class="literal">Observable</code> sends a notification by calling a method in each of the <code class="literal">Observer</code>s. The observers implement the <code class="literal">Observer</code> interface, which specifies that notification causes an <code class="literal">Observer</code> object’s <code class="literal">update()</code> method to be called.</p><p>In the following example, we create a <code class="literal">MessageBoard</code> object that holds a <code class="literal">String</code> message. <code class="literal">MessageBoard</code> extends <code class="literal">Observable</code>, from which it inherits the mechanism for registering observers (<code class="literal">addObserver()</code>) and notifying observers (<code class="literal">notifyObservers()</code>). To observe the <code class="literal">MessageBoard</code>, we have <code class="literal">Student</code> objects that implement the <code class="literal">Observer</code> interface so that they can be notified when the message changes:</p><a id="I_11_tt758"/><pre class="programlisting"> <code class="c1">//file: MessageBoard.java</code> <code class="kn">import</code> <code class="nn">java.util.*</code><code class="o">;</code> <code class="err"> </code> <code class="kd">public</code> <code class="kd">class</code> <code class="nc">MessageBoard</code> <code class="kd">extends</code> <code class="n">Observable</code> <code class="o">{</code> <code class="kd">private</code> <code class="n">String</code> <code class="n">message</code><code class="o">;</code> <code class="err"> </code> <code class="kd">public</code> <code class="n">String</code> <code class="nf">getMessage</code><code class="o">()</code> <code class="o">{</code> <code class="k">return</code> <code class="n">message</code><code class="o">;</code> <code class="o">}</code> <code class="kd">public</code> <code class="kt">void</code> <code class="nf">changeMessage</code><code class="o">(</code> <code class="n">String</code> <code class="n">message</code> <code class="o">)</code> <code class="o">{</code> <code class="k">this</code><code class="o">.</code><code class="na">message</code> <code class="o">=</code> <code class="n">message</code><code class="o">;</code> <code class="n">setChanged</code><code class="o">();</code> <code class="n">notifyObservers</code><code class="o">(</code> <code class="n">message</code> <code class="o">);</code> <code class="o">}</code> <code class="kd">public</code> <code class="kd">static</code> <code class="kt">void</code> <code class="nf">main</code><code class="o">(</code> <code class="n">String</code> <code class="o">[]</code> <code class="n">args</code> <code class="o">)</code> <code class="o">{</code> <code class="n">MessageBoard</code> <code class="n">board</code> <code class="o">=</code> <code class="k">new</code> <code class="n">MessageBoard</code><code class="o">();</code> <code class="n">Student</code> <code class="n">bob</code> <code class="o">=</code> <code class="k">new</code> <code class="n">Student</code><code class="o">();</code> <code class="n">Student</code> <code class="n">joe</code> <code class="o">=</code> <code class="k">new</code> <code class="n">Student</code><code class="o">();</code> <code class="n">board</code><code class="o">.</code><code class="na">addObserver</code><code class="o">(</code> <code class="n">bob</code> <code class="o">);</code> <code class="n">board</code><code class="o">.</code><code class="na">addObserver</code><code class="o">(</code> <code class="n">joe</code> <code class="o">);</code> <code class="n">board</code><code class="o">.</code><code class="na">changeMessage</code><code class="o">(</code><code class="s">"More Homework!"</code><code class="o">);</code> <code class="o">}</code> <code class="o">}</code> <code class="c1">// end of class MessageBoard</code> <code class="err"> </code> <code class="kd">class</code> <code class="nc">Student</code> <code class="kd">implements</code> <code class="n">Observer</code> <code class="o">{</code> <code class="kd">public</code> <code class="kt">void</code> <code class="nf">update</code><code class="o">(</code><code class="n">Observable</code> <code class="n">o</code><code class="o">,</code> <code class="n">Object</code> <code class="n">arg</code><code class="o">)</code> <code class="o">{</code> <code class="n">System</code><code class="o">.</code><code class="na">out</code><code class="o">.</code><code class="na">println</code><code class="o">(</code> <code class="s">"Message board changed: "</code> <code class="o">+</code> <code class="n">arg</code> <code class="o">);</code> <code class="o">}</code> <code class="o">}</code></pre><p>Our <code class="literal">MessageBoard</code> object extends <code class="literal">Observable</code>, which provides a method called <a id="I_indexterm11_id750509" class="indexterm"/><code class="literal">addObserver()</code>. Each <code class="literal">Student</code> object registers itself using this method and receives updates via its <code class="literal">update()</code> method. When a new message string is set using the <code class="literal">MessageBoard</code>’s <code class="literal">changeMessage()</code> method, the <code class="literal">Observable</code> calls the <a id="I_indexterm11_id750547" class="indexterm"/><code class="literal">setChanged()</code> and <code class="literal">notifyObservers()</code> methods to notify the observers. <code class="literal">notifyObservers()</code> can take as an argument an <code class="literal">Object</code> to pass along as an indication of the change. This object—in this case, the <code class="literal">String</code> containing the new message—is passed to the observer’s <code class="literal">update()</code> method as its second argument. The first argument to <code class="literal">update()</code> is the <code class="literal">Observable</code> object itself.</p><p>The <code class="literal">main()</code> method of <code class="literal">MessageBoard</code> creates a <code class="literal">MessageBoard</code> and registers two <code class="literal">Student</code> objects with it. Then it changes the message. When you run the code, you should see each <code class="literal">Student</code> object print the message as it is notified.</p><p>You can imagine how you could implement the observer/observable relationship yourself using a <code class="literal">List</code> to hold the list of observers. In <a class="xref" href="ch16.html" title="Chapter 16. Swing">Chapter 16</a> and beyond, we’ll see that the Java AWT and Swing event model extends this design pattern to use strongly typed observables and observers, which are called events and event listeners. But for now, we turn our discussion of core utilities to another fundamental topic: I/O.<a id="I_indexterm11_id750647" class="indexterm"/><a id="I_indexterm11_id750654" class="indexterm"/></p></div></body></html>