Thursday, September 12, 2013

JavaScript : OOP part 3

if (!theFrontier.final()) {theFrontier.current(true, 'part 3');}


How does JavaScript work as an object oriented language?

Very practically, in fact. So - let's get into some code...


A Singleton Pattern in C#...

public class Singleton
{
   private static Singleton instance;

   private Singleton() {}

   public static Singleton Instance
   {
      get 
      {
         if (instance == null)
         {
            instance = new Singleton();
         }
         return instance;
      }
   }
}
Singletons are useful when you don't want multiple instances of an object. Definitively, a singleton should be used in situations when there must be only one instance of a class or object. In the example above, the constructor is private and the instance itself is private. This creates a scenario where the developer accesses and uses the Singleton object via the public Instance member, which actually returns the private static instance of the Singleton object. If the private static instance is null, the object is instantiated before it returns. Once instantiated, it will remain instantiated. In other words - when Singleton.Instance is called, if the private static instance has already been instantiated, return it for use and if not, instantiate it - then return it for use. Personally, I like to coalesce the private instance, but that isn't really important.


A Singleton Pattern in JavaScript...

  "use strict";
  var Singleton = function() {
    var instanceName = "";
    if (Singleton.prototype.instance) {
      return Singleton.prototype.instance;
    }
    Singleton.prototype.instance = this;

    this.setInstanceName = function(n){
       instanceName = n;
    };
    this.getInstanceName = function(){
       return instanceName;
    };
  };
Here's a fiddle demonstrating its use:
It's not very different from the C# example! When we instantiate the Singleton object in javascript, if the Singleton.prototype.instance is not undefined, return the Singleton.prototype.instance for use - and if it is undefined, instantiate Singleton.prototype.instance with the current object's scope/execution context (aka the this), then return the object for use. In other words - when new Singleton() is called, if the Singleton.prototype.instance has already been instantiated, return it for use and if not, instantiate it - then return it for use.

Here's the same example, with the singleton stuff commented out:

A Factory Pattern in C#...

public static class CheesecakeFactory
{
   public static ICheesecake GetNewYorkCheesecake()
   {
       return new NewYorkCheesecake();
   }
   public static ICheesecake GetStrawberryCheesecake()
   {
       return new StrawberryCheesecake();
   }
   public static ICheesecake GetToastedSmoresCheesecake()
   {
       return new ToastedSmoresCheesecake();
   }   
   public static ICheesecake Create(CheesecakeConfig config)
   {
       return new Cheesecake{
           Name = config.CheesecakeName;
           Flavor = config.CheesecakeFlavor;
           Size = config.CheesecakeSize;
       };
   }
}
Factories are useful when you want to organize the instantiation of objects into some logical division or encapsulation. Definitively, they are an abstraction of a constructor or constructors. They are used pretty frequently in software development because they are useful. Architecturally, they can really help organize an application.


A Factory Pattern in JavaScript...

var CheesecakeFactory = {
    GetNewYorkCheesecake: function () {
        return new NewYorkCheesecake();
    },
    GetStrawberryCheesecake: function () {
        return new StrawberryCheesecake();
    },
    GetToastedSmoresCheesecake: function () {
        return new ToastedSmoresCheesecake();
    },
    Create: function (config) {
        var ck = new Cheesecake();
        ck.Name = config.CheesecakeName;
        ck.Flavor = config.CheesecakeFlavor;
        ck.Size = config.CheesecakeSize;
        return ck;
    }
};
Here's a fiddle demonstrating a javascript factory pattern:
While very similar to the C# example, you can see javascript showing some of its dynamic colors. The javascript CheesecakeFactory is an object literal (or namespace - if you will). By calling the CheesecakeFactory factory's member functions, we're return new instances of objects. Easy peasy, right?

A Fluent Interface in C#...

public static class FluentCheesecaker
{
   public static ICheesecake SetName(this ICheesecake cake, string name)
   {
       cake.Name = name;
       return cake;
   }
   public static ICheesecake SetFlavor(this ICheesecake cake, string flavor)
   {
       cake.Flavor = flavor;
       return cake;
   }
   public static ICheesecake SetSize(this ICheesecake cake, string size)
   {
       cake.Size = size;
       return cake;
   }
}
Fluent interfaces are a nice way to set up and/or configure an object. They exist to provide a means of doing just that (configuring or setting up objects), leaving code more readable.


A Fluent Interface in JavaScript...

var Cheesecake = function () {
    this.Name = '';
    this.Flavor = '';
    this.Size = '';
    return this;
}
Cheesecake.prototype.setName = function (n) {
    this.Name = n;
    return this;
}
Cheesecake.prototype.setFlavor = function (f) {
    this.Flavor = f;
    return this;
}
Cheesecake.prototype.setSize = function (s) {
    this.Size = s;
    return this;
}
Here's a fiddle demonstrating a javascript fluent interface:


As you can see, by returning the scope/execution context (the this) of the instance, the object method is chainable, returning the instance with each subsequent function call. The example uses the object's prototype to extend the object by adding the functions to its prototype, but you could do the same thing without touching the prototype.


Here's a fiddle demonstrating a javascript fluent interface WITHOUT using the object's prototype:





No comments:

Post a Comment