-
Get a monthly update on best practices for delivering successful software.
If you read good books, when you write, good books will come out of you. -- Natalie Goldberg
I first started fiddling with Open Source software somewhere in the mid to late 80's. I was strictly a download and compile guy at the time, but Unix variants being what they were, I was soon up to my elbows in makefiles and C in order to get the darn things to work. From there it wasn't that big of a leap from hacking around to reading the code, and reading code was a truly mind expanding experience.
Up to that time I had just been reading code from books -- little toy programs designed to illustrate a point rather than for production -- and had not been exposed to all of the idioms and approaches that were out there in the wild. You have to read and write lots of bad code before you write good code. And I did plenty of that, even contributing some code here and there to early Open Source projects. I would often download code just to read, not even to compile and install. At one stage I got really into Literate Programming and wrote several large systems using this Knuth inspired approach to writing human readable code. (I found, however, that few in the business world actually value documentation, especially when the deadline clock is ticking.)
One thing is for certain: I learned an awful lot, both on what to do and not do, from reading all that Open Source code. It expanded my world from just books and the handful of programmers I worked with on a daily basis to a cummunity of hundreds and, later, thousands of talented programmers. I stole their ideas and techniques with ruthless abandon. To this day I still read Java, C# and Javascript code in the hopes of finding new ideas and idioms. I even take my code to bed with me to read it before drifting off to sleep.
One of the areas where books are pretty lousy is OO Javascript. Most of the books will let you know how to create your own classes as well as doing some basic inheritance. But beyond a few toy examples, they won't help you in writing real code. Where to look? The major Javascript libraries -- Prototype, YUI, etc. -- have a variety of approaches to OOP. My own preference is for the style adopted by YUI, very similar to that suggested here, here and here, which allows you to chain constructors. My reasons for preferring this approach? I use an excellent and cheap UML modeling program call Enterprise Architect to generate code from models. A more traditional approach to inheritance like YUI's makes writing code generating templates for EA easier.
YUI's approach is short, but not necessarily simple:
YAHOO.extend = function(subclass, superclass) { var f = function() {}; f.prototype = superclass.prototype; subclass.prototype = new f(); subclass.prototype.constructor = subclass; subclass.superclass = superclass.prototype; if (superclass.prototype.constructor == Object.prototype.constructor) { superclass.prototype.constructor = superclass; }};
The punchline here is that you can now call the superclass methods and constructors from the subclass.
YAHOO.widget.SimpleDialog = function(el, userConfig) { YAHOO.widget.SimpleDialog.superclass.constructor.call(this, el, userConfig);};
YAHOO.extend(YAHOO.widget.SimpleDialog, YAHOO.widget.Dialog);
YAHOO.widget.SimpleDialog.prototype.initDefaultConfig = function() { YAHOO.widget.SimpleDialog.superclass.initDefaultConfig.call(this);
// Add dialog config properties // this.cfg.addProperty("icon", { value:"none", handler:this.configIcon, suppressEvent:true } ); this.cfg.addProperty("text", { value:"", handler:this.configText, suppressEvent:true, supercedes:["icon"] } );};
Prototype, JQuery and company have a somewhat different approach to inheritance. There's no constructor chaining, but there are a few more ways to inheriting behavior. For example, in Prototype 1.4, the extend function copies the properties from a base object to a subclass object:
Object.extend = function(destination, source) { for (property in source) { destination[property] = source[property]; } return destination;}
It's a bit more primitive, but can be chained like so: Object.extend(Object.extend(Ajax.Updater.prototype, Ajax.Request.prototype),...
The Yahoo approach to private versus public instance variables and methods is one of commenting and naming. Private instance members and methods are prefixed with a '_' except when they are not. In either case they are commented so as to identify whether the member or method is private or public. Dojo, on the other hand, makes some use of closures and inner functions to enforce the whole public/private thing (see Douglas Crockford's post on this).
One thing that is common to just about all of these frameworks is excellent documentation. Have a dynamic language like Javascript without strong typing and heavy use of idioms puts the burden on the developer to document the code, e.g. from Dojo dojo.io.setIFrameSrc = function(/*DOMNode*/ iframe, /*String*/ src, /*Boolean*/ replace).... I'm looking forward to Javascript 2 with it's support of real classes.
This just scratches the surface of what these various frameworks have to offer. Read code, make notes, save snippets, and improve your own code.
Related posts:
Topics: Ajax Development, Best Practices
great news – I’d been looking for someone to explain YAHOO.extend and I think I’m getting it now. Well, apart from this bit
if (superclass.prototype.constructor == Object.prototype.constructor) { superclass.prototype.constructor = superclass; }
Comment by dh, Wednesday, December 6, 2006 @ 5:02 pm