Monday, 5 September 2011

A Blackboard Object: OOP Javascript/jQuery On Html5 Canvas Demo

Javascript has evolved into a sophisticated programming language, and as such it has its own built-in objects as well as affording developers the possibility of creating their own custom objects. Here's my Blackboard object, a custom javascript object created as a stripped down version of my previous drawing board demo application. What are the advantages of using OOP (Object Oriented Programming) in javascript? How did I go about creating my Blackboard object?


OOP Javascript: Advantages



Modern physics has excellent grounds for claiming that there's an immense difference between the world as we see and perceive it and the world as it is independently of our everyday perception of it.  The latter is mostly composed of energy charges interspersed with as yet not adequately understood elementary particles.

In order for us to manage our environment, to know and interact with it successfully, our brains process the information coming from our sense organs in such a way as to create a meaningful world of self-contained, solid, inter-relating objects categorized according to specific features, characteristics, capacities, etc.

Powerful programming languages such as C#, PHP, etc., take up this same object model to construct "intelligent" artifacts with which we interact on a daily basis. Javascript offers to some extent the opportunity to benefit from this clever model.

All of my demos so far present some javascript/jQuery implementation. However, I've avoided using custom objects, at best I've used simple functions that I could conveniently call when needed. The main reason for this is that mine have been simple one-page, one-author demos, therefore requiring no long-term maintenance, no significant increase in complexity, and no danger of my code conflicting with anyone else's code. However, coding best practices recommend packing up one's javascript code into self-contained objects. Here are some of the main advantages of doing so, that I've tried to illustrate by means of some features of my Blackboard object.

Advantage #1: Separation between public and private


Objects in a program usually offer a public face, that is, the properties and methods that developers other than the original programmer can access to use the object (i.e., a programming interface), and a hidden place storing the inner variables and functions that only the original author of the program needs to access. Therefore, the developer using the interface simply sets a publicly accessible property, or calls a publicly accessible method of the object, without any need to know the intricacies in the ways in which the object's property acquires a given value, or the ways in which the object is enabled to perform a piece of functionality.

For example, to use my Blackboard object, I simply need to call "Blackboard.draw()" after the page has loaded in the browser, and the program does its thing. The actual functions that I use to implement free line drawing using the HTML5 Canvas API (which, incidentally, uses the same OOP principles), need not be known by me in order to have the functionality working in my application. A further consequence is that the same object can easily be distributed and reused in multiple applications and by several developers without any need for them to concern themselves with the inner mechanisms of the program.

Advantage #2: Minimize potential conflicts with other scripts


If your application implements different scripts, perhaps written by other developers, there might arise serious risks of conflicts among them. For instance, what if my program uses a variable called 'height' and another script referenced in the same page also uses a variable called 'height'? The 2 variables will hold different values, but will be referenced by the same name in the same page; this can only mean one thing: Bug Alert!

Taking my Blackboard as a way of illustrating the point, note that I don't call the draw() method directly from the page; instead, I call the draw() method of the Blackboard object, i.e., Blackboard.draw(). Therefore, if someone else implements a "draw()" method in the same page, the two will not conflict.

Advantage #3: Maintainability and extensibility


OOP offers the advantage of maintainable, more flexible, compact scripts. An OOP script appears as an ordered, hierarchical series of logically and functionally inter-related code chunks.

Taking once again the Blackboard object as illustration, whoever might have to review, debug, or maintain it, would have the job facilitated by the fact that the script is well-ordered and meaningful as a self-contained javascript object. First of all, we have the Blackboard object skeleton:

var Blackboard =
{
//javascript code here
}

It's a single global variable, imaginatively called Blackboard, followed by a set of curly braces. These will contain all the object's properties (such features as height, width, color, etc.) and methods (i.e., functions enabling the object to do stuff on the page). The notation is as follows: "property name: property value", function name: function() {}"; each property/method is separated by a comma.

At the very top, I've included a couple of variables that I find more convenient to pass around throughout the object's methods (I've kept these to a very low number). One will hold the canvas drawing context, the other is just a flag to alert the app if the eraser is on or off; here they are marked with an underline:

var Blackboard = 
{
context: null,
eraserActive: false,
}

The draw() method is next. This contains all the code that usually goes into the page load, including initializing variables and binding event handlers to the appropriate events. This is the outer function that will be called on page load and that makes use of the internal functions needed by the application to do its job, in this case to enable users to write stuff on the blackboard; here's just the first method call as soon as the page loads:

draw: function() {
this.context = this.getContext('myCanvas');
}

The keyword "this" indicates the object whose property value is being set or whose method is being called, in this case the Blackboard (I could just as well have written: "Blackboard.context"). Here I call the first internal function needed to draw on the canvas, that is the one that returns the drawing context. This is called getContext(), and its declaration is located further down, just below the draw() function, and looks like this:

getContext: function(canvasId) {
var canvas = document.getElementById(canvasId);
if (canvas.getContext) {
this.context = canvas.getContext('2d');
return this.context;
}
else {
alert('Update or change your browser');
}
},

Finally, the remaining methods deal with the actual Html5 Canvas API operations needed to draw free-hand lines on the board and to erase the board contents. For instance, the latter is very short, and looks like this:

clearBoard: function() {
this.context.clearRect(0, 0, 500, 500);
}

It will be called from the draw() function when the appropriate link is clicked in the following way:

$('#clearAll').click(function(e) {
Blackboard.clearBoard();
e.preventDefault();
});

Notice how the clearBoard() method call is prefixed by the object name, Blackboard (not the keyword "this"; in fact, this is so because the code is inside an event handler attached to the click event of a specific link element, hence "this" here refers to the link element being clicked rather than to the Blackboard object; the latter has therefore to be called explicitly.), and a dot (.), which indicates that the method does indeed belong to the Blackboard object.

Besides being well-ordered and easily maintainable, OOP code is also more flexible. For instance, a programmer could take the Blackboard object and adapt it to its taste and requirements just by modifying, or adding to, the properties and methods that are already there, rather than rewriting an entire script.

Summary


To conclude, although I'm not an expert on OOP javascript programming, I share the view that packaging code into custom objects when working on all but simple or trivial pieces of code, offers significant benefits and conforms to best programming practices. I might not always feel like it's the most straightforward way of doing things, but it gets better and better with practice and, most of all, with self-discipline.

Feel free to visit the live demo page and peek through the view source context menu to have a closer look at the heavily commented code (I've put both css and javascript in the same page as the html mark-up rather than in separate files just for convenience, as this is a simple one-page demo).

What's your experience of using OOP with javascript? Have you come up with more advantages of using OOP that you'd like to share? I look forward to hearing your comments on the subject.

3 comments:

  1. Excellent pieces. Keep posting such kind of information on your blog. I really impressed by your blog.
    Vee Eee Technologies

    ReplyDelete
  2. Beautiful! Very Beautiful. I just started your js tutorial on html.net. Js offers very many possibilities.

    ReplyDelete
  3. Thanks for your comments, I appreciate your interest.

    ReplyDelete