Sunday, February 28, 2010

Practical Object-Oriented JavaScript

In my last post, I provided insight into a object oriented design pattern for JavaScript that I've been using. In this post I want to show a practical implementation of the design pattern.

In the example below I have implemented the abstraction of a base class, Vehicle, with different sub classes: Car, Bike and Truck. The goals I have set out to illustrate this are:
  1. declare public methods in the base class, to be inherited in the different vehicle types
  2. define public variables, accessed through public methods (able to be overloaded)
  3. define a private variable, only utilized within a method from the base class unable to be modified unless overloading the public class calling it
  4. create a constructor that inits and requires arguments
  5. create a constructor in the base classes that overloads an argument ONLY if present
  6. simulate the 'super' call from within the constructor, like in Java

The model:

Vehicle [Parent]
   |
   +--- Car [Child]
   |
   +--- Bike [Child]
   |
   +--- Truck [Child]

The Code:

The organization of the code above has the base class as well as the sub classes within ONE closure. This means that private variables within this closure are directly accessible to other sub-classes as well, in effect making those private variables act like Java's 'protected' variables to the sub classes, and remaining invisible to the global NS.

Equally acceptable is breaking out the various subclasses into their own separate closures ((function(){****})()), but then of course the private variables available in the base class, are not directly available in the extending object's scope. If the base class has a required private variable that needs to be accessed from inheriting classes, there should be a public helper method (appended to the prototype) to access it.

Now let's see an example of using the defined classes:

This code prints out:

VEHICLE is a CAR, Model is a Honda Civic
VEHICLE is a CAR:SPORTS CAR, Model is a BMW m3
VEHICLE is a CAR:FAST SPORTS CAR, Model is a Porsche Turbo
VEHICLE is a BIKE, Model is a Ducati 999
VEHICLE is a TRUCK, Model is a Chevy Silverado 1500

If you've understood the model so far I'd appreciate any feedback. Same goes for anyone having difficulty understanding what i'm getting at. I'm new to blogging and I want to make sure that what i'm writing is as clear and straight-forward as possible.

In my next post I will share what I have found to be the basics for a JavaScript 'framework', and possible package structures.

Saturday, February 27, 2010

Object-Oriented JavaScript

If you want to learn about Object-Oriented programming applied to JavaScript, a quick search would result in articles and blogs that illustrate the various different characteristics (polymorphism,inheritance,encapsulation,etc) in action. Personally, I'de suggest nefarious-designs and Mozilla's reference; they're both comprehensive and very well written.

I am assuming that if you are reading this you are familiar with OO design. Being a Java developer it's natural for me to try to apply the pattern when working in other languages. Over the past few years I have helped setup and co-architect several websites, and each time I do, I gain a deeper appreciation for the need to apply the paradigm on the front-end (in JavaScript).

Particularly with the increasingly AJAX-ified nature of web applications, the simplification of development made possible thanks to libraries like jQuery, and browsers like Google Chrome pushing the limits, implementing and maintaining libraries is becoming ever more important.

The implementation that I have pursued is by no means the 'perfect solution', but I have found that it works in satisfying the following criteria --
  1. Readable, maintainable and unit-testable code
  2. Minimizes namespace collisions
  3. Increased velocity in development
  4. Modularity in code design (inheritence)
  5. Subtype polymorphism
  6. Encapsulation (appropriate variable scoping for public & private vars)

1. Singleton/Utility


The singleton can be referenced as SINGLETON (it's in the global namespace). All methods appended to the prototype can be referenced on the SINGLETON object, i.e. SINGLETON.method(). All methods that are created within the self-executing closure are private, available within the public prototypical methods and are not extended to the global NS.

2. Java Pojo Equivalent


Base Class


The above code utilizes the self-executing function to achieve appropriate scoping of variables and methods. To instantiate a pojo, as per usual: var pojo = new Pojo();

Amongst the most important use of the OO design pattern is utilizing inheritence (re-using already constructed code). In Java, a class can inherit attributes from a base class by using the word 'extends'. In JavaScript an object that is created can be instantiated as a reference pointer to the class that is to be extended, i.e. NewPojo = Pojo.

Sub Class (extends Base Class)


Notice that publicVar is overloaded in this case by defining the variable on the object's prototype. The same can be applied to methods inherited in XPojo from Pojo. Note again, that the self-executing function allows for scoping variables in either private or public scope.

Finally, what about using "super", in reference to the extended base class, in the overloading methods?

Notice that in order to gain a 'super' reference like in Java, a DIRECT pointer to the public method in the BASE CLASS must be defined in JavaScript (through the prototype). And to invoke the method simply use the native 'call' method on the Function object.

Finally, I know that JavaScript is a prototype based programming language, and I'm applying the class inheritance based model to it. But coming from a Java background and needing to understand scalable JavaScript solutions, I've really been able to grow in my abilities by understanding the parallels.

That's all for now. I hope this post gave some insight into a possible implementation of the object-oriented design paradigm in JS. In my next post I will show practical implementations of the design pattern.