Welcome to Cykod. We are a fully-integrated, self-funded web-development startup located in Boston, MA.

Know when to punt: Deferring intelligently

Larger project generally have a large set features that need to be developed and large set of features that could benefit from existing functionality available in libraries and off the shelf components.

Large projects furthermore all suffer from one issue whether you acknowledge it or not: incomplete specs.

No matter how good you are at what developing specifications and software, if you're building something you've never built before, 99% of the time your not going to have a perfect design at the moment when development commences.

The Agile methodology is built on this concept, but even if you don't necessarily subscribe to "the whole agile thing" - experience in software development should give some truth to the above paragraph. If not, well you are either lying to yourself, were recently hit over the head with a large object, or you are just that good in which case you can stop reading as the rest doesn't apply to you.

For the rest of us, the reasons we have incomplete specs are pretty varied, here's some examples
- You never wrote complete specs to begin with
- The client doesn't know what they want
- Feedback from early prototypes has led to changes
- The client modifies the requirements
- Different 3rd party libraries have different features and you don't know which to use

And there's plenty more (e.g. the US economy crashes in the worst recession in a century and the client slices the budget in half)

Regardless, should any of these happen, the specs you have are effectively incomplete (even if you don't know it). What this means is that even if you could through all of Google's crack developer staff at your project, you couldn't finish it right away because there are still design decisions to be made.

What this means is that there are certain parts of the project whose development you are going to need to put off for the time being. This can be a problem if other parts of the project need to use that component or if you need to get a quick prototype up that uses features of that component.

... figure out a way to defer a making a hard decision on that component while still doing what needs to be done to keep the project going forward.

You have two options: One, even knowing that the specs for that component might change, go full steam ahead! and get something in there. Or two, figure out a way to defer a making a hard decision on that component while still doing what needs to be done to keep the project going forward.

What's wrong with 1? If you don't have all the information necessary to make the decision, you really shouldn't be making it if there's another way.

Let's say your project needs to incorporate video but you don't know what types yet. If you go ahead and integrate a 3rd party library that only supports quicktime, then you are going to be in a for some painful extraction process down the road when you need to support AVI and OGG down the road. If you went ahead and tightly coupled your code to 1 specific library, that extraction process is going to be even more painful.

You'd like to put off deciding on a video library but if video is a big part of your project, your boss will want to see some video in there sooner rather than later.

Here's where the Adapter Pattern comes into great use. Instead of coupling to a specific video library, ask yourself what do you need a video library to do, maybe all you need is:

Video#new(filename)
Video#stop()
Video#start()
Video#seek(offset_from_start)

Now lets say the video library you are looking at offers the following functions:

XYZVideo#new(read_type,base_bath,file_type,filename,option_A,option_B)
XYZVideo#play(offset)
XYZVideo#pause(remember_location=true)
XYZVideo#reset
XYZVideo#fastForward(time)
XYZVideo#rewind(time)
...And 50 other methods you don't actually need


Creating a wrapper class around the XYZVideo library will give you the simple interface that you need, but you'll be able to quickly integrate video into you project - and your project won't be peppered with implementation-specific details about accessing your video.

Even better, write some unit tests on your Video class, and then in two months when you invariably switch libraries, you'll already have tests written that will let you determine if you're new video library is working the same way as the old one.

Going back to the idea of deferring - if you really don't have the specs for video nailed down, you could even skip the library for now and just output a static frame instead of actually linking up to a real library. This will give the rest of the project time to fill out around the video requirements and any changes to you imagined video interface will be extremely easy to implement.

A couple months down the line - the other code in the project will have defined exactly the interface that you'll need for you video library and you'll be able to drop in the perfect 3rd party library that fits your need and budget.

Two caveats to this:

using an adapter pattern has some downsides. First, it's more project-specific code to maintain and secondly it's more code that gets run during execution so it can slow your project down some. Written correctly, the first problem is not a big deal as it reduces coupling between components and third party libraries, so the effect of a 3rd party library with different conventions and coding styles will be minimized and your code base should look more uniform for the most part. The performance issue is also not usually a big deal, except when you're using an adapter pattern at too fine grain a detail - if a co-worker comes in and says - What if we will want a different for(;;) loop implemention later in the project? Easiest solution: throw something (light) at them. Used correctly, most of the time the total performance hit is a couple of extra stack pushs and jumps, but performance issues are something to keep in mind.

Bottom line, if some parts of a project are unclear, put them off. It's better to put off writing code if you can when you don't know what you want to write. 

Second caveat, make sure you aren't overusing the Adapter pattern for the wrong reasons. If your project is called KSuperApplication, it's probably ok to use the KDE libraries as that's part of the point. Also you shouldn't really be using Adapter's to adapt your own code base to your own code base. If that's the case you probably have some bigger architectures issues you need to work out (this is sometimes necessary with legacy code)

Bottom line, if some parts of a project are unclear, put them off. It's better to put off writing code if you can when you don't know what you want to write. This isn't always possible, but sometimes you can get away with deferring decisions by focusing on the features you do know that you need and generating a stub or an adapter class to expose just those features and hide the rest of the details from the rest of the code.

 

Posted Friday, Sep 04 2009 05:49 AM by Pascal | Development

Leave a Comment

Display Name:


Your Email (Optional, not displayed):

Add a Comment:

captcha