Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

addressing more items from the technical review

  • Loading branch information...
commit ea6af5e4eaf97d99886b7d20744892c6501a65bb 1 parent d98692e
Addy Osmani authored

Showing 1 changed file with 24 additions and 17 deletions. Show diff stats Hide diff stats

  1. 41  book/index.html
41  book/index.html
@@ -2072,11 +2072,12 @@ <h2 id="drypatternjavascript">The DRY Pattern </h2>
2072 2072
 
2073 2073
 
2074 2074
 // Let's store some defaults about a car for reference
2075  
-var defaultSettings = {};
2076  
-defaultSettings['carModel']   = 'Mercedes';
2077  
-defaultSettings['carYear']    = 2010;
2078  
-defaultSettings['carMiles']   = 5000;
2079  
-defaultSettings['carTint']    = 'Metallic Blue';
  2075
+var defaultSettings = {
  2076
+    carModel: 'Mercedes',
  2077
+    carYear:  '2010',
  2078
+    carMiles: '5000',
  2079
+    carTint:  'Metallic Blue';
  2080
+};
2080 2081
 
2081 2082
 // Let's do something with this data if a checkbox is clicked
2082 2083
 $('.someCheckbox').click(function(){  
@@ -2376,7 +2377,7 @@ <h2 id="decoratorpatternjavascript">The Decorator Pattern</h2>
2376 2377
     } 
2377 2378
 }
2378 2379
 </pre>
2379  
-<p>Next, we&#39;ll want to specify a new class (object) that&#39;s a subclass of the existing Person object. Let&#39;s imagine we want to add distinct properties to distinguish a Person from a Superhero whilst inheriting the properties of the Person &#39;superclass&#39;. As superheroes share many common traits with normal people (eg. name, gender), this should hopefully illustrate how subclassing works adequately.</p>
  2380
+<p>Next, we&#39;ll want to specify a new class (object) that&#39;s a subclass of the existing <code>Person</code> object. Let&#39;s imagine we want to add distinct properties to distinguish a <code>Person</code> from a <code>Superhero</code> whilst inheriting the properties of the <code>Person</code> &#39;superclass&#39;. As superheroes share many common traits with normal people (eg. name, gender), this should hopefully illustrate how subclassing works adequately.</p>
2380 2381
 <pre  class="brush: js">    
2381 2382
 //a new instance of Person can then easily be created as follows:
2382 2383
 var clark = new subclassExample.Person( &quot;Clark&quot; , &quot;Kent&quot; );
@@ -2396,11 +2397,11 @@ <h2 id="decoratorpatternjavascript">The Decorator Pattern</h2>
2396 2397
 var superman = new subclassExample.Superhero( &quot;Clark&quot; ,&quot;Kent&quot; , [&#39;flight&#39;,&#39;heat-vision&#39;] );
2397 2398
 console.log(superman); /* includes superhero props as well as gender*/
2398 2399
 </pre>
2399  
-<p>The Superhero definition creates an object which descends from Person. Objects of this type have properties of the objects that are above it in the chain and if we had set default values in the Person object, Superhero is capable of overriding any inherited values with values specific to it&#39;s object.</p>
  2400
+<p>The <code>Superhero</code> definition creates an object which descends from <code>Person</code>. Objects of this type have properties of the objects that are above it in the chain and if we had set default values in the <code>Person</code> object, <code>Superhero</code> is capable of overriding any inherited values with values specific to it&#39;s object.</p>
2400 2401
 <p>So where do decorators come in?</p>
2401 2402
 <h2>Decorators</h2>
2402 2403
 <p>Decorators are used when it&#39;s necessary to delegate responsibilities to an object where it doesn&#39;t make sense to subclass it. A common reason for this is that the number of features required demand for a very large quantity of subclasses. Can you imagine having to define hundreds or thousands of subclasses for a project? It would likely become unmanagable fairly quickly.</p>
2403  
-<p>To give you a visual example of where this is an issue, imagine needing to define new kinds of Superhero: SuperheroThatCanFly, SuperheroThatCanRunQuickly and SuperheroWithXRayVision.</p>
  2404
+<p>To give you a visual example of where this is an issue, imagine needing to define new kinds of <code>Superhero</code>: SuperheroThatCanFly, SuperheroThatCanRunQuickly and SuperheroWithXRayVision.</p>
2404 2405
 <p>Now, what if superhero had more than one of these properties?. We&#39;d need to define a subclass called SuperheroThatCanFlyAndRunQuickly , SuperheroThatCanFlyRunQuicklyAndHasXRayVision etc - effectively, one for each possible combination. As you can see, this isn&#39;t very manageable when you factor in different abilities.</p>
2405 2406
 <p>The decorator pattern isn&#39;t heavily tied to how objects are created but instead focuses on the problem of extending their functionality. Rather than just using inheritance, where we&#39;re used to extending objects linearly, we work with a single base object and progressively add decorator objects which provide the additional capabilities. The idea is that rather than subclassing, we add (decorate) properties or methods to a base object so its a little more streamlined.</p>
2406 2407
 <p>The extension of objects is something already built into JavaScript and as we know, objects can be extended rather easily with properties being included at any point. With this in mind, a very very simplistic decorator may be implemented as follows:</p>
@@ -2473,7 +2474,7 @@ <h2 id="decoratorpatternjavascript">The Decorator Pattern</h2>
2473 2474
 console.log(mb.cost()); //1522
2474 2475
 console.log(mb.screenSize()); //13.3
2475 2476
 </pre>
2476  
-<p>Here, the decorators are overrriding the superclass .cost() method to return the current price of the Macbook plus with the cost of the upgrade being specified. It&#39;s considered a decoration as the original Macbook object&#39;s constructor methods which are not overridden (eg. screenSize()) as well as any other properties which we may define as a part of the Macbook remain unchanged and intact.</p>
  2477
+<p>Here, the decorators are overrriding the superclass <code>.cost()</code> method to return the current price of the <code>Macbook</code> plus with the cost of the upgrade being specified. It&#39;s considered a decoration as the original <code>Macbook</code> object&#39;s constructor methods which are not overridden (eg. <code>screenSize()</code>) as well as any other properties which we may define as a part of the <code>Macbook</code> remain unchanged and intact.</p>
2477 2478
 <p>As you can probably tell, there isn&#39;t really a defined &#39;interface&#39; in the above example and duck typing is used to shift the responsibility of ensuring an object meets an interface when moving from the creator to the receiver.</p>
2478 2479
 <h2>Pseudo-classical decorators</h2>
2479 2480
 <p>We&#39;re now going to examine the variation of the decorator presented in &#39;Pro JavaScript Design Patterns&#39; (PJDP) by Dustin Diaz and Ross Harmes.</p>
@@ -2573,29 +2574,35 @@ <h2 id="decoratorpatternjavascript">The Decorator Pattern</h2>
2573 2574
         }        
2574 2575
 };
2575 2576
 </pre>
2576  
-<p>What&#39;s happening in the above sample is that the Macbook decorator is taking an object to use as the component. It&#39;s using the Macbook interface we defined earlier and for each method is just calling the same method on the component. We can now create our option classes just by using the Macbook decorator - simply call the superclass constructor and any methods can be overriden as per necessary.</p>
  2577
+<p>What&#39;s happening in the above sample is that the Macbook decorator is taking an object to use as the component. It&#39;s using the Macbook interface we defined earlier and for each method is just calling the same method on the component. We can now create our option classes just by using the Macbook decorator - simply call the superclass constructor and any methods can be overridden as per necessary.</p>
2577 2578
 <pre  class="brush: js">var CaseDecorator = function( macbook ){
2578 2579
     /*call the superclass&#39;s constructor next*/
2579 2580
     this.superclass.constructor(macbook);    
2580 2581
 }
  2582
+
2581 2583
 /*Let&#39;s now extend the superclass*/
2582 2584
 extend( CaseDecorator, MacbookDecorator ); 
  2585
+
2583 2586
 CaseDecorator.prototype.addCase = function(){
2584 2587
     return this.macbook.addCase() + &quot; Adding case to macbook &quot;;   
2585 2588
 };
  2589
+
2586 2590
 CaseDecorator.prototype.getPrice = function(){
2587 2591
     return this.macbook.getPrice() + 45.00;  
2588 2592
 };
2589 2593
 </pre>
2590 2594
 <p>As you can see, most of this is relatively easy to implement. What we&#39;re doing is overriding the addCase() and getPrice() methods that need to be decorated and we&#39;re achieving this by first executing the component&#39;s method and then adding to it.</p>
2591 2595
 <p>As there&#39;s been quite a lot of information presented in this section so far, let&#39;s try to bring it all together in a single example that will hopefully highlight what we&#39;ve learned.</p>
2592  
-<pre  class="brush: js">//Instantiation of the macbook
  2596
+<pre  class="brush: js">// Instantiation of the macbook
2593 2597
 var myMacbookPro = new MacbookPro();  
2594  
-//This will return 900.00
  2598
+
  2599
+// This will return 900.00
2595 2600
 console.log(myMacbookPro.getPrice());
2596  
-//Decorate the macbook
  2601
+
  2602
+// Decorate the macbook
2597 2603
 myMacbookPro = new CaseDecorator( myMacbookPro ); /*note*/
2598  
-//This will return 945.00
  2604
+
  2605
+// This will return 945.00
2599 2606
 console.log(myMacbookPro.getPrice());
2600 2607
 </pre>
2601 2608
 <p>An important note from PJDP is that in the line denoted <strong>note</strong>, Harmes and Diaz claim that it&#39;s important not to create a separate variable to store the instance of your decorators, opting for the same variable instead. The downside to this is that we&#39;re unable to access the original macbook object in our example, however we technically shouldn&#39;t need to further.</p>
@@ -2839,8 +2846,8 @@ <h2 id="detailmvc">MVC</h2>
2839 2846
 <p>What this provides us with is a very lightweight, simple way to manage changes between the model and the view.</p>
2840 2847
 <p><strong>Backbone.js</strong></p>
2841 2848
 <p>Later on in this section we&#39;re going to revisit the differences between Backbone and traditional MVC, but for now let&#39;s focus on controllers.</p>
2842  
-<p>In Backbone, one shares the responsibility of a controller with both the Backbone.View and Backbone.Router. Some time ago Backbone did once come with it&#39;s own Backbone.Controller, but as the naming for this component didn&#39;t make sense for the context in which it was being used, it was later renamed to Router.</p>
2843  
-<p>Routers handle a little more of the controller responsibility as it&#39;s possible to bind the events there for models and have your view respond to DOM events and rendering. As Tim Branyen (another Bocoup-based Backbone contributor) has also previously pointed out, it&#39;s possible to get away with not needing Backbone.Router at all for this, so a way to think about it using the Router paradigm is probably:</p>
  2849
+<p>In Backbone, one shares the responsibility of a controller with both the <code>Backbone.View</code> and <code>Backbone.Router</code>. Some time ago Backbone did once come with it&#39;s own <code>Backbone.Controller</code>, but as the naming for this component didn&#39;t make sense for the context in which it was being used, it was later renamed to Router.</p>
  2850
+<p>Routers handle a little more of the controller responsibility as it&#39;s possible to bind the events there for models and have your view respond to DOM events and rendering. As Tim Branyen (another Bocoup-based Backbone contributor) has also previously pointed out, it&#39;s possible to get away with not needing <code>Backbone.Router</code> at all for this, so a way to think about it using the Router paradigm is probably:</p>
2844 2851
 <pre  class="brush: js">var PhotoRouter = Backbone.Router.extend({
2845 2852
   routes: { &quot;photos/:id&quot;: &quot;route&quot; },
2846 2853
 
@@ -4097,7 +4104,7 @@ <h1 id="detailnamespacing">Namespacing Patterns</h1>
4097 4104
 <p>That&#39;s it for IIFEs for the time-being. If you would like to find out more about this pattern, I recommend reading both Ben&#39;s <a href="http://benalman.com/news/2010/11/immediately-invoked-function-expression/">IIFE post</a> and Elijah Manor&#39;s post on <a href="enterprisejquery.com/2010/10/how-good-c-habits-can-encourage-bad-javascript-habits-part-1/">namespace patterns from C#</a>.</p>
4098 4105
 <h3>5. Namespace injection</h3>
4099 4106
 <p>Namespace injection is another variation on the IIFE where we &#39;inject&#39; the methods and properties for a specific namespace from within a function wrapper using <i>this</i> as a namespace proxy. The benefit this pattern offers is easy application of functional behaviour to multiple objects or namespaces and can come in useful when applying a set of base methods to be built on later (eg. getters and setters).</p>
4100  
-<p>The disadvantages of this pattern are that there may be easier or more optimal approaches to achieving this goal (eg. deep object extension / merging) which I cover earlier in the article..</p>
  4107
+<p>The disadvantages of this pattern are that there may be easier or more optimal approaches to achieving this goal (eg. deep object extension / merging) which I cover earlier in the section.</p>
4101 4108
 <p>Below we can see an example of this pattern in action, where we use it to populate the behaviour for two namespaces: one initially defined (utils) and another which we dynamically create as a part of the functionality assignment for utils (a new namespace called <i>tools</i>).</p>
4102 4109
 <pre  class="brush: js">var myApp = myApp || {};
4103 4110
 myApp.utils =  {};

0 notes on commit ea6af5e

Please sign in to comment.
Something went wrong with that request. Please try again.