Principles of Web Application Development

Technical

Anyone that's been building web applications (or doing anything else, for that matter) for any length of time has undoubtedly established a few operating principles that drive the way they work and the deliverables they produce. I have mine. Not too long ago, I sat down and made an effort to articulate the principles (well, at least the big ones) that drive my work and, after some thought, decided to publish them here. I'd be interested in hearing how others apply (or avoid) the principles that I follow.

Keep It Simple, Stupid

This principle has been covered in a myriad of other places and, in the context of the modern web (call it web 2.0 if you must), seems self-evident if not obvious. Nonetheless, this is an overarching, guiding principle and an entry about an approach to developing web applications just can't ignore it simply on the grounds that it's trite or redundant; it's that important. It's no accident that it appears first on my list.

Simplicity in Design

I'm always surprised how many people I talk to that still want something spinning, turning, changing, blinking, shifting or otherwise verb-ing on their site. Especially on the homepage. Oy. In my mind, the argument for these things is the same as the argument against. I always hear, "It will draw the visitor's eye." My answer is always the same, "True, but...it will draw the visitor's eye." Once a visitor is on a page, that spinning, turning, changing, blinking, shifting or verb-ing thing is just a distraction. While s/he is trying to read the page's carefully crafted content, that thing keeps right on spinning, turning, changing, blinking, shifting or verb-ing. Each time it does, the visitor's eye is naturally drawn to the change (the eye is pretty remarkable in its ability to recognize movement peripherally) which serves only to disrupt his or her flow. Now that eye-catching whos-a-ma-bob is just annoying.

I don't mean to suggest that there can't be any movement on the page. There can be. Just be (very) judicious about it and keep it subtle.

Simplicity in Markup

Simplicity goes beyond the view from the outside; it includes the view from the inside - the markup and CSS. Site visitors won't see this unless developers have so overindulged in complexity that load time is affected, but other developers - current and future - will. They'll appreciate any effort made to maintain simplicity. I'm going to ask you to trust me on that. I've spent years maintaining some pretty obscene code (much of it my own). These are lessons learned the hard way.

The key to simplicity in markup, I think, is semantics. If the markup is semantic then it's written for the content to define the content and, if done right, includes only what's necessary to affect that content. When markup is approached this way, simplicity is a nearly inevitable result. To borrow from Louis Sullivan, "Form follows function." In my own words, "a little is so much easier to write and maintain than a lot".

Hey, I never claimed that this was rocket science.

Simplicity in Code

I don't have any tried and true, specific advice for keeping code simple. By "code", I mean the scripting language that makes applications, well, applications rather than billboards; code is a much more varied animal than markup. That said, I'll offer this high-level insight that I often fall back on when talking to other members of my team: if it seems like there should be a better way, there probably is a better way.

There's room for intuition and down-home gut feeling in the linear process of development. Embrace it and trust it.

Separate Content from Presentation

Again, something that's covered elsewhere (nearly everywhere), but is so...on the nose...that it can't be ignored. How? Start with no inline styles. Period. This is non-negotiable. Ditto embedded stylesheets. Inline styles and embedded stylesheets undo the very thing that made stylesheets so useful when they were originally introduced, um, years ago. The idea was to be able to modify the appearance of a site element everywhere that element appeared by making a single change to a stylesheet. Apply those styles in the style attribute of those individual elements and the result is nothing more than glorified presentational markup.

Embedded stylesheets are better, but only because they're a lesser degree of the same kind of error. They should still be avoided, I think, and for most applications, anything that can be done in an embedded stylesheet can be - and is better - done in an external stylesheet.

Separate Content from Behavior

In the same way, and for the same reason, as content, behavior should also be removed from the markup. Instead, apply behaviors by adding listeners to elements after the DOM is loaded. Javascript libraries make this even easier than it used to be. Consider an FAQ, for example. The page displays a series of questions whose answers are hidden. When one of the questions is clicked, the answer to that question is displayed. To do this, a click event handler must be applied to the question's DOM element. To illustrate, I'll use the following markup:

<div id="faq">
    <h4>Why is it so hard to separate content from behavior?</h4>
    <p>It's not.  It's really not.</p>
    <h4>How can I accomplish this separation?</h4>
    <p>External source files that detect page load and apply event handlers.</p>
</div>

It's easy enough to add event handlers to each h4 element in the markup, sure, but that approach introduces redundant code. In jQuery, adding an event handler to show/hide answers is as simple as this:

$(document).onReady (
    function() {
        $('#faq h4').click (
            function() {
                $(this).next().toggle();
            }
        )
    }
);

When the DOM is loaded, a click event handler is applied to every h4 descendant of the faq div. It's a trivial matter to place this code (and other code like it) in an external JavaScript source file. Now it doesn't have to be hunted down or changed in multiple places and common code can be shared by adding it to the same file.

Prefer Extensibility to Performance

The eternal conflict. I read something a long time ago that's stuck with me to this day: Design for extensibility, code for performance. I can't give proper credit, but suffice to say those aren't my words. They are, however, words I try to apply to every solution I work on.

Don't sacrifice proper engineering at the alter of performance. An application's architecture must be able to evolve and scale over time; inevitably it will be asked to do so. Understand that from the start and allow for that capability without respect to the overhead created by, say, separating the domain model from its data access layer.

Prefer Readability to Performance

The eternal conflict, redux. Readability should always take precedence over marginal performance increases. Developers will have to use their own judgment when determining whether a performance increase is worth the reduced readability and how far to reduce readability in order to gain performance. Never lose sight of the fact that readability has a direct impact on maintainability.

Finally, do not reduce readability unless there are known performance issues. To do so is to commit the sin of premature optimization. Much has been written about that concept. Google it. It's important. It probably deserves a spot on this list, but instead it got two. This principle and the last exist solely to avoid the trap of premature optimization.

Prefer Simplicity to Flexibility

The more customize-ability that's added, the more ways that are added to access a certain feature, the more attempts that are made to please everyone...the less happy everyone's going to be. Flexibility almost necessarily adds complexity and no one likes complexity. For visitors, it means more stuff they've got to figure out; for developers, more stuff they have to maintain. My experience has been that the folks for whom the flexibility was added are, at the very best, apathetic to the "convenience" they've been offered and rarely avail themselves of it, so what's the point? Better to start with less and add to that based on customer feedback. Which leads us to...

Less First, Then More

A variation of Louis Sullivan's famous quote, but I hope he'll forgive me. When conceiving an application, determine what's truly necessary to make that application viable. Build that and stop. More accurately, pause.

It's tempting to build the kitchen sink version, but remember that conceiving an application's feature set and requirements is effectively an academic exercise to the analysts, business owners and stakeholders. The application will be used by its intended audience and, with luck, integrated into their daily workflow. For that audience, it's no longer academic. My experience has been that the feedback given by those customers is often vastly different from much of what was cooked up in the lab environment.

Integrate customer feedback with any initial requirements that were left out and a project roadmap begins to take shape.

Chad said:
 
Rob, I agree with everything you've listed. One item that seems to be missing is the DRY principle. I know you've mentioned it on your blog before, and perhaps it's implied by what you've stated here.
 
posted 313 days ago
View Replies (1) || Add Comment Reply to: this comment OR this thread
 
.: HIDE REPLIES :.
 
Good point. DRY, in my mind, is a result of extensibility in design, but I should have mentioned it explicitly because it's 2 or 3 steps removed.

In fact, if I sit and think about it, I'm not even sure that DRY is really a _goal_ of well-engineered software, it's more of a logical - and almost accidental - _result_ of well-engineered software. I'll have to put some thought into that. I'd be interested in seeing whether I can articulate it better.

On the other hand, maybe it's just a derivative of the old chicken and egg argument. Either way, I should have mentioned it. Thanks for pointing out the omission.
 
posted 313 days ago
Add Comment Reply to: this comment OR this thread
 

Search

Rob  Wilkerson