Thoughts on coding and new classes as a result…

Thursday, September 4th, 2008 @ 5:07 pm | filed under: Best Practices, CNET JS Standards, Organizing Code, Widgets

A short while back I was helping out a coworker who was working on a content management system with a very rich UI. In helping him work out some of the issues he was struggling with, I had one of those rare moments where I conceived of a better way to write my own code.

Some of his struggles were performance related – he had a LOT going on, but those were really an extension of the fact that his code was kind of all over the place. What started as an interface with some nice enhancements had grown into a behemoth of functions, namespaces, dom references and conventions that he couldn’t hope to keep straight anymore.

Part of what I suggested to him was that he start treating items on the page as widgets. Every portion of the interface could be broken up into little bits of functionality with a corresponding (MooTools) class and then larger items would be comprised of these smaller things. The larger items would have their own classes as well. These would act like controllers for the smaller ones.

Over the next few weeks he refactored his code and when I saw him it was aparent that he was much happier. Relieved even. The result is a structured family of functionalities that each correspond to little chunks of his UI. He can combine these in various ways for different use cases and work flows. He can extend the classes when he needs something that’s slightly different.

His sense of relief was so apparent that I began rethinking my own approach to my code.

Previously I had divided my code into two types: what I called “implementation” code and code designed to be reused.

The implementation code was the code you had to write for a specific page and, for that reason, wasn’t reusable. It references specific dom elements and is taylored to the user experience. Reusable code was the stuff that was generic. Slideshows, date pickers, etc.

After helping my friend with his work, I began to think of all of my code as reusable. In theory, the only non-reusable stuff is the stuff that explicitly references the DOM. As a result, I started writing classes for everything, no matter how trivial. My pages would have a minimal amount of code and the only thing this could would do is instantiate these classes.

For example, if, previously, I had code that toggled an element from being hidden to visible (using Fx.Reveal) did something like this:

$('clicker').addEvent('click', function(){
$('section').retrieve('reveal').toggle();
});

I would instead write a class that would look like this:

var Collapsable = new Class({
Extends: Fx.Reveal,
initialize: function(clicker, section, options) {
this.clicker = $(clicker).addEvent('click', this.toggle.bind(this));
this.parent($(section), options);
}
});

It’s not much more code, but now I can recreate the same thing on my page with just:

new Collapsable($('clicker'), $('section'));

Dividends

The result of this method of thinking gave me much the same sense of happiness that my friend found when he applied it to his work. At first, as I worked, I’d find myself repeatedly turning away from my specific task and writing some generic class. Any time I wanted to write more than new Something… I’d have to go write a class. It felt like slow progress.

But over time, a few things began to become clear.

  • New pages took less and less time as I built up a little group of widget classes
  • Stuff I never thought I’d actually reuse turned out to get used again
  • I found myself extending the simple classes that I thought would have limited use and developing little families of functionality
  • My pages themselves had less and less code on them

Maybe this isn’t new to some of you. I definitely feel that I’ve been writing JavaScript too long to still be having these kinds of realizations, though maybe I appreciate them when they happen all the more because they do happen less frequently than they used to…

New Classes in the CNET Libs

After a bit of work, I took a few of these little widgets and put them into the CNET Libraries and released them. Unfortunately, this type of development is not so good for release. It’s not that these little widgets aren’t useful, but rather that they take about 10 times longer to release than they do to write. What might be a day of development might yield a week’s worth of work to release. When you consider that for every class we release there are docs, tests or specs, and tutorials, it adds up fast. That little widget example I gave above (Collapsable) took me maybe 2 minutes to write, but an hour to release. Yikes!

Consequently, I think that I’ll start putting these things into the SVN repository for people to play with as I write them and then formally release them in batches.

In the mean time, here’s a list of the new things available as of today (click the links to see demos):

  • Element.nix – Uses Fx.Reveal to hide an element and then removes it from the DOM – think of it as Element.erase (or Element.destroy) with a transition.
  • Collapsable – The example above – uses Fx.Reveal to toggle the visibility of an element when another element is clicked. Think of it as an Accordion for one item.
  • Chain.Wait – Lets you introduce pauses to chains. For example, you could tween an element to be visible, then use this wait method to wait a moment, then fade it back out:
    new Fx.Tween('el', {link: 'chain', property: 'opacity'}).tween(1).wait(1000).tween(0);
  • Class.Binds – The Binds Mutator used by a few other people in the MooTools dev group. This will likely be in 1.3. See the tutorial for details
  • Fupdate – Handles the rather popular pattern that submits a form via ajax and updates a specified DOM element with the result
  • Fupdate.append – The same as Fupdate, except that it appends the result into the target element instead of overwriting the contents
  • Fupdate.prompt – Fupdate and Fupdate.append with the form in a popup

Btw, Fupdate is a pretty week name, but I’ve been stumped to come up with something else, so if you have any ideas, do share.

Your thoughts?

What do you think of this new (to me) approach? Do you think any of these widgets above are likely to be useful to you? Do you write your own code this way? I’m curious what others here think of this approach.

11 Responses to “Thoughts on coding and new classes as a result…”

  1. bryanjswift Says:

    I’ve been slowly progressing my method of development to something much closer to this. I admit I’m not there yet and I’m not sure I’ll get there without forcing the issue but as I’ve recently written a couple of pages with similar functionality but different in specific and relatively minor ways I find myself wanting to undertake a major refactoring. If only I could find the time for it.

  2. rexxars Says:

    I think it’s a good way of coding, and shows you just how much you reuse things if it’s available. Personally, I find myself doing a lot of the old addEvent(‘click’) stuff, so I’m definately going to try and adapt to making more reusable classes.

    I think there’s a typo in your Class.Binds example, it references this.boundAlert, which I believe should be refering to just alert in that last example.

    Nice work on releasing the classes, you saved me some time with these :-)

  3. jducoeur Says:

    I tend to take a somewhat more middle-ground approach, focused on refactoring.

    When I’m just writing something for the first time, I’ll simply write it out in-place. But I try to be absolutely strict about never duplicating code. If I find myself writing the same thing again — even just a few lines of code, or sometimes even a single line with complex parameters — then that indicates to me that refactoring may be called for. At that point, I’ll lift that code out into a method, or a separate class/widget if the functionality cuts across class lines.

    This approach seems to strike a good balance: rather than trying to guess in advance what is going to be reusable, I keep a close eye on my code and let the reusable bits emerge as I write. That way, I don’t spend too much time on factoring the code excessively, but still avoid code duplication (which is the root of most programming evils).

    If you haven’t read it, I commend Martin Fowler’s book “Refactoring”. It’s one of those programming bibles that is worthwhile for every programmer…

  4. sivoh Says:

    I think your strategy of dividing the page into widgets backed by JavaScript classes is absolutely the way to go. The benefits of this style of programming go beyond reusability, however. Much of the functionality of a moderately complicated client-side application will be patently non-reusable, but this code must still be encapsulated as if it were going to be reused. Writing code as if it were going to be reused forces you to disconnect it from the rest of the application. The fewer connections the code contains, the easier it is to add, modify and debug the code, because changes to the code are much less likely that to affect other parts of the application. Failing to properly encapsulate code leads to the complexity death that is a common source of project failures (especially in rich-client projects). Reusability itself is great when it works out, but it can actually have a negative effect on overall code complexity if the classes lack a well defined purpose and straightforward API.

  5. Aaron N. Says:

    My apologies to all here who posted a reply to this – I didn’t realize that I had new posts to moderate (indeed, I was a bit miffed that my post didn’t elicit even a single reply). Something’s fishy with my wordpress install as it doesn’t seem to be emailing me…

    Regardless, this is all great feedback. Regarding jducoeur’s suggestions on refactoring, I think that your approach is a matter of discipline. I’ve found that if I don’t do this kind of management as I’m writing the code, I don’t tend to get back around to it. Maybe two months later, on a different project, I’ll think “This is just like that thing I did a month or two ago…” and the 5 or 10 or 30 lines of code needed to replicate it don’t merit revisiting that older code.

    I’ve found that since I started working this way that things that I would never consider reusable to come around more than I would have guessed, and the fact that they are already portable increases the likelihood that I’ll use it.

    I agree with sivoh’s comments about the other value – that it decreases complexity. Or, maybe it’s that the complexity is more defined. You know where the touch points are of the application instead of getting this big spaghetti mess of functions and stand-alone code.

    -Aaron

  6. Darren K Says:

    I have to admit, when I first read your article I thought, “Big deal. I’m already doing pretty much the same thing by organizing my scripts into objects and functions.” Like you, I figured most of it was site specific and couldn’t really be reused in other sites. Then I got to wondering, “Is that really true?” Even on the basic end, I always apply menu rollovers the same way, and if I want to vertically center an element there’s no real reason to rewrite that code snippet each time even though it’s only four lines.

    So when I started my latest project, every time I wanted to do something, I thought about whether I could put my code into a class or an element extension. Sure enough, nearly all of my code was reusable and I simply hadn’t been taking the time to put it into a reusable form. I’d been reusing functions within site applications, but hadn’t been thinking about how things could be reused between sites. My current project is small, but just making this small change in my thinking has drastically cut the main code base and dramatically increased the code organization (which I honestly thought was pretty good before).

    I don’t know if anyone else has similar tendencies, but it’s amazing how much more strict I am about organization when building a class. Maybe it’s just me, but as soon as I turn something into a class I have the overwhelming urge to break it down into as many discrete functions as possible. So not only have I produced a lot of reusable code, but the quality of that code is much better than it would have been otherwise.

    Thanks for sharing your thoughts. I’ll certainly be trying to build things with more of an eye towards reusability from now on.

  7. Aaron N. Says:

    Glad to hear you’re having a similar experience to me, Darren. I went through the same thing. After I thought, “well, my code is in pretty good shape.” But the more I considered it the more I realized that using classes pays these dividends. I do the same thing as you – when I write a quick function as part of a page’s setup, I just bang it out. But when I write a class I’m much more critical and careful.

  8. jQuery, MooTools, and the Ajax Experience, Programming to the Pattern, and What Really Makes One Framework Different From Another » Clientside Says:

    [...] in talking to Bill, I spoke about some of my recent thinking about what I’ve been calling “Programming to the Pattern.” It goes something like [...]

  9. Inspired by Aaron Newton’s “Programming to the Pattern” | Garrick Cheung Says:

    [...] and the care-taker of Clientside, CNET.com’s developer blog. He recently wrote about being inspired to write code differently and a more indepth post about his thoughts on (take a deep breath if you’re verbally reading [...]

  10. Teejay Says:

    I haven’t been reading the blog lately but having read this post, I have begun to change my coding style with regards to Mootools.

    Extensible coding with Mootools makes me feel good in a way.

  11. Mooish Repository Template and an All-JsonP Showcase » Clientcide (Formerly CNET's Clientside) Says:

    [...] source of the site itself is all cleanly written MooTools classes, reminding me of my thoughts on programming to [...]