Permalink
Browse files

merging observer pattern sections to avoid repeating

  • Loading branch information...
1 parent f982626 commit 8108825cc5a6a0efc4c05fa6d07afd3cefa5551f @addyosmani addyosmani committed Apr 6, 2012
Showing with 72 additions and 237 deletions.
  1. +72 −237 book/index.html
View
309 book/index.html
@@ -1274,38 +1274,90 @@ <h2 id="revealingmodulepatternjavascript">The Revealing Module Pattern</h2>
<p>&nbsp;</p>
-
<p>&nbsp;</p>
<p>&nbsp;</p>
<h2 id="observerpatternjavascript">The Observer Pattern</h2>
-<!-- todo:update-->
+<p>The Observer pattern is more popularly known these days as the Publish/Subscribe pattern. It is a design pattern which allows an object (known as a subscriber) to watch another object (the publisher), where we provide a means for the subscriber and publisher form a listen and broadcast relationship. </p>
+
+<p>Subscribers are able to register (subscribe) to receive notifications from the publisher when something interesting happens. When the publisher needs to notify observers about interesting events, it broadcasts (publishes) a notification of these events to each observer (which can include specific data related to the event).</p>
+
+<p>When subscribers are no longer interested in being notified by the publisher they are registered with, they can unregister (or unsubscribe) themselves. The subject will then in turn remove them from the observer collection.</p>
+
+<p>
+ The general idea here is the promotion of loose coupling. Rather than single objects calling on the methods of other objects directly, they instead subscribe to a specific task or activity of another object and are notified when it occurs.</p>
+
+<p>
+It's often useful to refer back to published definitions of design patterns that are language agnostic to get a broader sense of their usage and advantages over time. The definition of the observer pattern provided in the GoF book, <em>Design Patterns: Elements of Reusable Object-Oriented Software</em>, is:</p>
+
+<p>
+<h3>'One or more observers are interested in the state of a subject and register their interest with the subject by attaching themselves. When something changes in our subject that the observer may be interested in, a notify message is sent which calls the update method in each observer. When the observer is no longer interested in the subject's state, they can simply detach themselves.'</h3>
+</p>
+
+<p>
+Unlimited numbers of objects may observe events in the subject by registering themselves. Once registered to particular events, the subject will notify all observers when the event has been fired.</p>
+
+<p>Further motivation behind using the observer pattern is where you need to maintain consistency between related objects without making classes tightly coupled. For example, when an object needs to be able to notify other objects without making assumptions regarding those objects. Another use case is where abstractions have more than one aspect, where one depends on the other. The encapsulation of these aspects in separate objects allows the variation and re-use of the objects independently. </p>
+
+<h2>Advantages</h2>
-<p>The Observer pattern (also known as the Publish/Subscribe model) is a design pattern which allows an object (known as an observer) to watch another object (the subject) where the pattern provides a means for the subject and observer to form a publish-subscribe relationship. It is regularly used when we wish to decouple the different parts of an application from one another.</p>
+<p>
+Arguably, the largest benefit of using Pub/Sub is the ability to break down our applications into smaller, more loosely coupled modules, which can also improve general manageability.
+</p>
+<p>
+It is also a pattern that encourages us to think hard about the relationships between different parts of your application, identifying what layers need to observe or listen for behaviour and which need to push notifications regarding behaviour occurring to other parts of our apps.</p>
-<p>Note that this is another pattern we'll be looking at in greater detail in the next section of the book.</p>
+<p>Dynamic relationships may exist between publishers and subscribes which can be easily established on page load. This provides a great deal of flexibility which may not be as easy to implement when disparate parts of your application are tightly coupled.</p>
-<p>Observers are able to register (subscribe) to receive notifications from the subject when something interesting happens. When the subject needs to notify observers about interesting events, it broadcasts (publishes) a notification of these events to each observer (which can include data related to the event). .</p>
+<p>
+Whilst it may not always be the best solution to every problem, it remains one of the best tools for designing decoupled systems and should be considered an important tool in any JavaScript developer's utility belt.</p>
-<p>The motivation behind using the observer pattern is where you need to maintain consistency between related objects without making classes tightly coupled. For example, when an object needs to be able to notify other objects without making assumptions regarding those objects. Another use case is where abstractions have more than one aspect, where one depends on the other. The encapsulation of these aspects in separate objects allows the variation and re-use of the objects independently. </p>
+<h2>Disadvantages</h2>
+<p>
+Consequently, some of the issues with this pattern actually stem from its main benefit. By decoupling publishers from subscribers, it can sometimes become difficult to obtain guarantees that particular parts of our applications are functioning as we may expect.</p>
<p>
-<strong>Advantages using the observer pattern include:</strong>
+For example, publishers may make an assumption that one or more subscribers are listening to them. Say that we're using such an assumption to log or output errors regarding some application process. If the subscriber performing the logging crashes (or for some reason fails to function), the publisher won't have a way of seeing this due to the decoupled nature of the system.</p>
+
+<p>Another draw-back of the pattern is that observers are quite ignorant to the existence of each other and are blind to the cost of switching in subject. Due to the dynamic relationship between subjects and observers the update dependency can be difficult to track.</p>
+
+<h2>Implementations</h2>
+
+<p>
+One of the benefits of design patterns is that once we understand the basics behind how a particular pattern works, being able to interpret an implementation of it becomes significantly more straight-forward.</p>
+
+
+<p>Luckily, popular JavaScript libraries such as dojo and YUI already have utilities that can assist in easily implementing your own Pub/Sub system.</p>
+
+<p>
+For those wishing to use the Pub/Sub pattern with vanilla JavaScript (or another library) AmplifyJS includes a clean, library-agnostic implementation of Pub/Sub that can be used with any library or toolkit. ScriptJunkie also has a tutorial on how to get started with Amplify's Pub/Sub that was recently published. You can of course also write your own implementation from scratch or also check out either PubSubJS or OpenAjaxHub, both of which are also library-agnostic.</p>
+
+<p>
+jQuery developers have quite a few options for Pub/Sub (in addition to Amplify) and can opt to use one of the many well-developed implementations ranging from Peter Higgins's jQuery plugin to Ben Alman's (optimized) gist on GitHub. Links to just a few of these can be found below.
+</p>
+
<ul>
- <li>Support for simple broadcast communication. Notifications are broadcast automatically to all objects that have subscribed.</li>
- <li>Dynamic relationships may exist between subjects and observers which can be easily established on page load. This provides a great deal of flexibility.</li>
- <li>Abstract coupling between subjects and observers where each can be extended and re-used individually.</li>
+<li>Ben Alman's Pub/Sub gist <a href="https://gist.github.com/661855">https://gist.github.com/661855</a> (recommended)</li>
+<li>Rick Waldron's jQuery-core style take on the above <a href="https://gist.github.com/705311">https://gist.github.com/705311</a></li>
+<li>Peter Higgins' plugin <a href="http://github.com/phiggins42/bloody-jquery-plugins/blob/master/pubsub.js">http://github.com/phiggins42/bloody-jquery-plugins/blob/master/pubsub.js</a>.</li>
+<li>AppendTo's Pub/Sub in AmplifyJS <a href="http://amplifyjs.com">http://amplifyjs.com</a></li>
+<li>Ben Truyman's gist <a href="https://gist.github.com/826794">https://gist.github.com/826794</a></li>
</ul>
-</p>
-<strong>Disadvantages</strong>
-<p>A draw-back of the pattern is that observers are ignorant to the existence of each other and are blind to the cost of switching in subject. Due to the dynamic relationship between subjects and observers the update dependency can be difficult to track.</p>
-<p>Let us now take a look at an example of the observer pattern implemented in JavaScript. The following demo is a minimalist version of Pub/Sub I released on GitHub under a project called <a href="http://github.com/addyosmani/pubsubz">pubsubz</a>. Sample usage of this implementation can be seen shortly.</p>
+<p>&nbsp;</p>
+
+<h2>Tutorial</h2>
<p>
-<h3>Observer implementation</h3>
+So that we are able to get an appreciation for how many of the vanilla JavaScript implementations of the Observer pattern might work, let's take a walk through of a minimalist version of Pub/Sub I released on GitHub under a project called <a href="http://github.com/addyosmani/pubsubz">pubsubz</a>. This demonstrates the core concepts of subscribe, publish as well as the concept of unsubscribing.</p>
+
<p>
+I've opted to base our examples on this code as it sticks closely to both the method signatures and approach of implementation I would expect to see in a JavaScript version of the original observer pattern.</p>
+
+
+<h3>Sample Pub/Sub implementation</h3>
+
<pre class="brush: js">
var pubsub = {};
@@ -1372,11 +1424,11 @@ <h2 id="observerpatternjavascript">The Observer Pattern</h2>
};
}( pubsub ));
</pre>
-</p>
-</p>
-<p>
-<h3>Observing and broadcasting</h3>
+
+
+<h3>Example 1: Basic use of publishers and subscribers</h3>
+
<p>We can now use the implementation to publish and subscribe to events of interest as follows:</p>
<p>
<pre class="brush: js">
@@ -1408,223 +1460,6 @@ <h2 id="observerpatternjavascript">The Observer Pattern</h2>
<p>A jsFiddle version of this example can be found at <a href="http://jsfiddle.net/LxPrq/">http://jsfiddle.net/LxPrq/</a></p>
</p>
-<p><strong>Note:</strong>If you are interested in a pub/sub pattern implementation using jQuery, I recommend Ben Alman's <a href="https://gist.github.com/661855">GitHub Gist</a> for an example of how to achieve this.</p>
-
-<p>&nbsp;</p>
-<p>&nbsp;</p>
-
-<!-- todo:rest of this to integrate -->
-<h1 id="detailedobserver">The Observer (Pub/Sub) pattern</h1>
-<p>&nbsp;</p>
-
-<p>
-As we saw earlier in the book, the general idea behind the Observer pattern is the promotion of loose coupling. Rather than single objects calling on the methods of other objects directly, they instead subscribes to a specific task or activity of another object and are notified when it occurs. Observers are also called Subscribers and we refer to the object being observed as the Publisher (or the subject). Publishers notify subscribers when events occur.</o>
-<p>
-When objects are no longer interested in being notified by the subject they are registered with, they can unregister (or unsubscribe) themselves. The subject will then in turn remove them from the observer collection.</p>
-<p>
-It's often useful to refer back to published definitions of design patterns that are language agnostic to get a broader sense of their usage and advantages over time. The definition of the observer pattern provided in the GoF book, <em>Design Patterns: Elements of Reusable Object-Oriented Software</em>, is:</p>
-
-<p>
-'One or more observers are interested in the state of a subject and register their interest with the subject by attaching themselves. When something changes in our subject that the observer may be interested in, a notify message is sent which calls the update method in each observer. When the observer is no longer interested in the subject's state, they can simply detach themselves.'
-</p>
-
-<p>
-Basically, the pattern describes subjects and observers forming a publish-subscribe relationship. Unlimited numbers of objects may observe events in the subject by registering themselves. Once registered to particular events, the subject will notify all observers when the event has been fired.</p>
-
-<h2>Advantages</h2>
-
-<p>
-Arguably, the largest benefit of using pub/sub is the ability to break down our applications into smaller, more loosely coupled modules, which can also improve general manageability.
-</p>
-<p>
-Pub/sub is also a pattern that encourages us to think hard about the relationships between different parts of your application, identifying what layers need to observe or listen for behaviour and which need to push notifications regarding behaviour occurring to other parts of our apps.</p>
-<p>
-Whilst it may not always be the best solution to every problem, it remains one of the best tools for designing decoupled systems and should be considered an important tool in any JavaScript developer's utility belt.</p>
-
-<h2>Disadvantages</h2>
-<p>
-Consequently, some of the issues with the pub/sub pattern actually stem from its main benefit. By decoupling publishers from subscribers, it can sometimes become difficult to obtain guarantees that particular parts of our applications are functioning as we may expect.</p>
-
-<p>
-For example, publishers may make an assumption that one or more subscribers are listening to them. Say that we're using such an assumption to log or output errors regarding some application process. If the subscriber performing the logging crashes (or for some reason fails to function), the publisher won't have a way of seeing this due to the decoupled nature of the system.</p>
-
-<h2>Implementations</h2>
-
-<p>
-One of the benefits of design patterns is that once we understand the basics behind how a particular pattern works, being able to interpret an implementation of it becomes significantly more straightforward. Luckily, popular JavaScript libraries such as dojo and YUI already have utilities that can assist in easily implementing your own pub/sub system.</p>
-
-<p>
-For those wishing to use the pub/sub pattern with vanilla JavaScript (or another library) AmplifyJS includes a clean, library-agnostic implementation of pub/sub that can be used with any library or toolkit. ScriptJunkie also has a tutorial on how to get started with Amplify's pub/sub that was recently published. You can of course also write your own implementation from scratch or also check out either PubSubJS or OpenAjaxHub, both of which are also library-agnostic.</p>
-
-<p>
-jQuery developers have quite a few options for pub/sub (in addition to Amplify) and can opt to use one of the many well-developed implementations ranging from Peter Higgins's jQuery plugin to Ben Alman's (optimized) gist on GitHub. Links to just a few of these can be found below.
-</p>
-
-<ul>
-<li>Ben Alman's Pub/Sub gist <a href="https://gist.github.com/661855">https://gist.github.com/661855</a> (recommended)</li>
-<li>Rick Waldron's jQuery-core style take on the above <a href="https://gist.github.com/705311">https://gist.github.com/705311</a></li>
-<li>Peter Higgins' plugin <a href="http://github.com/phiggins42/bloody-jquery-plugins/blob/master/pubsub.js">http://github.com/phiggins42/bloody-jquery-plugins/blob/master/pubsub.js</a>.</li>
-<li>AppendTo's Pub/Sub in AmplifyJS <a href="http://amplifyjs.com">http://amplifyjs.com</a></li>
-<li>Ben Truyman's gist <a href="https://gist.github.com/826794">https://gist.github.com/826794</a></li>
-</ul>
-
-<p>&nbsp;</p>
-
-<h2>Tutorial</h2>
-
-<p>
-So that we are able to get an appreciation for how many of the vanilla JavaScript implementations of the Observer pattern might work, let's take a walk through of a trimmed down version of Morgan Roderick's PubSubJS, which I've put together below. This demonstrates the core concepts of subscribe, publish as well as the concept of unsubscribing.</p>
-
-<p>
-I've opted to base our examples on this code as it sticks closely to both the method signatures and approach of implementation I would expect to see in a JavaScript version of the original observer pattern.</p>
-
-
-<h3>Sample Pub/Sub implementation</h3>
-
-<pre class="brush: js">
-
-var PubSub = {};
-
-(function(p){
-
- "use strict";
- var topics = {},
- lastUid = -1;
-
-
- var publish = function( topic , data){
-
- if ( !topics.hasOwnProperty( topic ) ){
- return false;
- }
-
-
- var notify = function(){
- var subscribers = topics[topic],
- throwException = function(e){
- return function(){
- throw e;
- };
-
- };
-
- for ( var i = 0, j = subscribers.length; i < j; i++ ){
- try {
- subscribers[i].func( topic, data );
- } catch( e ){
-
- setTimeout( throwException(e), 0);
- }
- }
- };
-
- setTimeout( notify , 0 );
- return true;
- };
-
-
-
- /**
- * Publishes the topic, passing the data to it's subscribers
- * @topic (String): The topic to publish
- * @data: The data to pass to subscribers
- **/
-
- p.publish = function( topic, data ){
- return publish( topic, data, false );
- };
-
-
- /**
- * Subscribes the passed function to the passed topic.
- * Every returned token is unique and should be stored if you need to unsubscribe
- * @topic (String): The topic to subscribe to
- * @func (Function): The function to call when a new topic is published
- **/
-
- p.subscribe = function( topic, func ){
-
- // topic is not registered yet
- if ( !topics.hasOwnProperty( topic ) ){
- topics[topic] = [];
- }
-
- var token = (++lastUid).toString();
- topics[topic].push( { token : token, func : func } );
-
- // return token for unsubscribing
- return token;
-
- };
-
- /**
- * Unsubscribes a specific subscriber from a specific topic using the unique token
- * @token (String): The token of the function to unsubscribe
- **/
-
- p.unsubscribe = function( token ){
-
- for ( var m in topics ){
- if ( topics.hasOwnProperty( m ) ){
- for ( var i = 0, j = topics[m].length; i < j; i++ ){
- if ( topics[m][i].token === token ){
- topics[m].splice( i, 1 );
- return token;
- }
- }
- }
- }
- return false;
- };
-});
-</pre>
-
-
-
-<h3>Example 1: Basic use of publishers and subscribers</h3>
-
-<p>
-This could then be easily used as follows:
-</p>
-
-<pre class="brush: js">
-// a sample subscriber (or observer)
-
-var testSubscriber = function( topics , data ){
- console.log( topics + ": " + data );
-
-};
-
-
-
-// add the function to the list of subscribers to a particular topic
-// maintain the token (subscription instance) to enable unsubscription later
-
-var testSubscription = PubSub.subscribe( 'example1', testSubscriber );
-
-
-
-// publish a topic or message asyncronously
-
-PubSub.publish( 'example1', 'hello scriptjunkie!' );
-
-PubSub.publish( 'example1', ['test','a','b','c'] );
-
-PubSub.publish( 'example1', [{'color':'blue'},{'text':'hello'}] );
-
-
-
-// unsubscribe from further topics
-setTimeout(function(){
- PubSub.unsubscribe( testSubscription );
-}, 0);
-
-
-
-// test that we've fully unsubscribed
-PubSub.publish( 'example1', 'hello again!');
-
-</pre>
<h3>Real-time stock market application</h3>
@@ -1901,7 +1736,7 @@ <h1 id="detailedobserver">The Observer (Pub/Sub) pattern</h1>
</pre>
-<strong>JAVASCRIPT</strong>:
+<strong>JavaScript</strong>:
<pre class="brush: js">
(function($) {

0 comments on commit 8108825

Please sign in to comment.