Welcome!

ColdFusion Authors: Maureen O'Gara, Hovhannes Avoyan, Yakov Fain, Pat Romanski, Liz McMillan

Related Topics: ColdFusion

ColdFusion: Article

Tipping Points: Little things that make a big difference

Tipping Points: Little things that make a big difference

In his new book, The Tipping Point: How Little Things Can Make a Big Difference (Little, Brown), Malcolm Gladwell makes the case for critical stages in the development of an endeavor.

Like tugboats steering a huge ocean liner, these "tipping points" wield enormous leverage, achieving results far beyond their apparent importance.

When, for example, the New York subway authorities decided to make subway riding safer and more comfortable, they placed their greatest efforts on two widespread but seemingly minor problems: graffiti and fare cheaters. The results were dramatic reductions in all subway infractions including violent crime and robbery. What caused this, Gladwell argues, is that these small crimes were tipping points that, when allowed to grow unchecked, poisoned the whole system.

I found the book interesting - so much so that I began making a list of the tipping points I see in software development. These are the little things I've found that create an inordinate impact on a project. See what you think.

1. Explain your development process to the customer.
At the beginning of a new project customers are excited about the boundless possibilities. Visions of what you will produce for them dance tantalizingly in their heads. In such an atmosphere it's pretty easy to get caught up in the euphoria. I sometimes think our conference room, where most of these meetings take place, should have a sign posted that echoes the warning on ancient maps about uncharted waters: "Here there be dragons."

It's important to remember that customers rely on us for more than just technical prowess. They come to us for guidance on the development of a software project, and they're almost never fully aware of its scope and complexity. It's my job - and maybe yours - to offer a firm, accomplished and helping hand along the way. Explaining the whole development process helps the customer understand what each of us will need to do.

2. Set clear project milestones spaced at short intervals.
I don't like the idea that we meet with a customer a few times, jot down some sketches and a few acronyms, then disappear into our coding lairs. Instead, I lay out our process graphically, explain the steps along the way and detail what each of us will be responsible for at each point. I tell them that as we continue along this path, we'll reach certain points or milestones that tell us where we've been and where we're going. Where the path winds back on itself, I explain the iterative nature of this section and that, to go forward, we must agree the milestone has been met.

Each milestone has a deliverable and marks a passage from one phase of the project to another. Now we get a little crazy with this. At each stage both the client and the development team sign off, certifying the milestone has been met. The prototype we're working on has visual indicators that we've moved from one phase to the next. At first glance it may all seem a little silly. I can only say that I prefer this harmless silliness to the outright lunacy of a development process that proceeds one step forward and two steps back.

3. Never mind involving customers - pester them.
I've done a lot of software proj-ects of all types - amazingly, all for the same customer. At least it seems that way. Whether the customer is a large corporation developing an e-commerce site, a government agency or a small start-up, they all want the same thing: "Build the application and then we'll tell you what we want."

Of course, they don't actually say this. Part of my job is to explain our development process, as described above. I tell clients that too often software developers involve customers at two points in the process. The first time is in the beginning, when it's too early to get their feedback on the work in progress. The next time, sadly, is when it's too late to do much about it.

My advice is to pester the customer. I like to say that customers and developers talk through prototypes. The customer tells us: "This is what I want," and we go back and put together a mock-up.

"Like this?" we ask - and we keep asking until we get it just right.

4. Resist the urge to code too soon.
It follows that we shouldn't code until we know what it is we're supposed to be coding! Somehow, though, that's easier said than done. I've often found myself chomping at the bit to start coding when I knew more upfront work had to be done. But hey! I like to code! Over time I've trained myself to wait until our prototyping efforts bear ripe fruit. If you're working with less experienced developers, you may find that they need a little encouragement to trust the process and wait...

You may have noticed that the skills and temperament needed to be an excellent coder often don't match the ones required of those folks who work with the customer to unearth requirements. It seems to work best if we don't put coders in this position. Coders should code, letting others skilled in analysis and user interface design add their expertise to the development mix.

When do we start coding? I find it best to wait until the customer tells us to. During my explanation of the development process I explain the notion of an "architectural freeze" - the point at which all prototyping and requirement gathering stops and coding actually begins. All projects must negotiate between the competing goals of speed-to-market and completeness of specifications. We let the customer determine the proper tradeoff by telling us when they want to go to architectural freeze. Our contracts specify delivery n weeks after architectural freeze.

5. Document your code before you write it.
This one seems a bit odd to many developers but you might want to give it a try. It's a wonderful discipline that helps you understand if you fully grasp both the broad lines and the individual details of a project. You'll probably uncover gaps in your knowledge, and the resulting documentation will help you standardize on naming conventions as well as reveal what functional objects are candidates for reusable components.

What documentation should you include? This depends on your methodology as well as your shop standards, but I generally suggest to people that they include:

  • Responsibilities of the fuse - what it's supposed to do
  • Author and subsequent editors of the code file
  • The variables directly passed to the code
  • Variables directly passed from the code
  • Global variables the coder needs to know of (e.g., session-, client- and application-scope variables)
  • Global variables the coder is responsible for setting
  • Subsidiary files (includes query files, functions, stylesheets, etc.) that the coder needs to be aware of

    If you haven't already standardized a documentation specification, you might consider my Fusedoc spec, outlined in the April issue of CFDJ (Vol. 2, issue 4).

    6. Adopt a consistent coding style.
    Admittedly, this is much more important if you're working with a team of programmers than by yourself, but all of us can benefit from this. I find it's most important when it's 3:00 a.m., five hours before a delivery deadline, and I'm debugging a particularly troublesome bit of code. Being able to scan a page of code that's consistently laid out is immensely helpful. When a new coder is brought onto a project, both this person and the existing team will benefit from a specified way of formatting code.

    It's not a matter of one way or the other being right. A former boss of mine used to shake his head and tell me about coders that were so obsessive they would take the time to reformat the code before they would work on it. "Imagine that..." I would mutter, looking away guiltily. So, to avoid the "curly braces war," we need to sit down at the negotiating table and agree on a common standard of practice.

    7. Test everything you write.
    Now I know this is second nature for you, but I have to have a prescribed method for doing this - or it'll stay an unrealized good intention. I do so by insisting that all unit-level code I write has a "test harness" accompanying it. The test harness sets up the appropriate environment (with the requisite variables defined and initialized) and runs my unit code.

    Of course, using Fusedoc is a great help as I can immediately tell what the proper environment should consist of. Your test harness can test for such common errors as nulls and boundary conditions (extremes on both ends of a continuum of values). I sometimes write the test harnesses before I write the code itself - gaining many of the benefits of writing documentation prior to the actual code.

    8. Try "pair programming."
    Uh-oh. I fear I've just lost many of you. This is one of those counterintuitive ideas that has to be tried out to be evaluated. Pair programming is two coders working on the same code at the same computer with a single keyboard/mouse.

    I can tell you that my own experience with pair programming has taught me to value it greatly. A natural rhythm develops in which one member of the pair buckles down to the immediate task while the other is thinking more broadly and strategically, exploring how this code may affect other code, possibly not yet written. These functions aren't permanent. When one member gets stuck - or just tired of typing - the places can be switched.

    Most pointy-haired bosses aren't overjoyed by the idea that one expensive programmer working on a single piece of code has been replaced by two expensive coders working...well, you get the point. Again, I can only suggest that you try it.

    9. Separate form from function.
    This isn't an easy task nor are there any sure, easy answers. Still, we can gain from "refactoring" our code - looking for areas where functions and data can be abstracted into nonvisual objects, complete with methods that can be accessed by other application pages. Without this, our code tends to get "smeared out" among many pages, making maintenance difficult and reuse almost impossible.

    You might also think about adopting a more formal methodology that supports the distinction between the model and the view, such as the one presented by Ralph Fiol in his fine work at www.cfobjects.com. Like a consistent coding standard, there's no right way, but applying the general principle of separation of form and function usually results in better code reuse and maintainability.

    10. Strive for simplicity.
    An old Shaker hymn tells us, "'tis a gift to be simple; 'tis a gift to be free." It may be a gift, but it certainly isn't easy to come by! Complexity and obscurity seem to achieve a life of their own, slipping uninvited into our code.

    For example, I recently looked at some convoluted code that was troubling a developer who was trying to maintain it. p> <cfloop from="1"to= "#ListLen(Trim
    (ValueList(myQ.Name)))#" index="i">
    #ListGetAt(ValueList(myQ.Name),i)#<br>
    </cfloop>

    I suggested that future coders called on to work on that particular code file would thank her if she rewrote it like this:

    <cfloop query="myQ">
    #name#<br>
    </cfloop>

    To put it simply, as my old boss used to say, "Sometimes, Hal, clever code is bad code."

    We developers can have an enormous influence on the world around us. The Internet - and the Internet economy - would never have developed had the pointy-haired managers been running the show. I hope that by examining my candidates for tipping points, you'll find your own way to leverage your own power - and maybe revolutionize the world again.

  • More Stories By Hal Helms

    Hal Helms is a well-known speaker/writer/strategist on software development issues. He holds training sessions on Java, ColdFusion, and software development processes. He authors a popular monthly newsletter series. For more information, contact him at hal (at) halhelms.com or see his website, www.halhelms.com.

    Comments (0)

    Share your thoughts on this story.

    Add your comment
    You must be signed in to add a comment. Sign-in | Register

    In accordance with our Comment Policy, we encourage comments that are on topic, relevant and to-the-point. We will remove comments that include profanity, personal attacks, racial slurs, threats of violence, or other inappropriate material that violates our Terms and Conditions, and will block users who make repeated violations. We ask all readers to expect diversity of opinion and to treat one another with dignity and respect.