Rob Cook

Home | Donate

Top down, bottom up


Debate goes on about the best way to approach a programming project. One of the principle questions is top down or bottom up? My answer these days is to use both.

There is a lure to top down design. Starting with the big ideas, the main abstractions, getting to design an architecture. These things can be seductive, they certainly where for much of my early programming career. But, this is not really programming. It is too far away from the machine, it avoids the messy details by hiding them under neat little boxes and arrows. You end up with a nice set of abstractions, but nothing that actually does anything.

So bottom up then? Without a guiding heuristic you are likely to end up with a big ball of mud. Perhaps one that functions correctly (for now), but certainly not one that is maintainable for any length of time. You need to know which direction you are heading in before you write the code.

I like to start projects these days with a deliberately minimal top down design session. By minimal I mean a page or two of sketches that outline the major parts of a system, boxes and arrows mainly. Resist the temptation to go beyond the most high level breakdown of parts. Don't architect anything, just think of it as giving directions to someone.

With that in place I like to pick a component and switch to a bottom up approach. These days I start by doing. Write code that does the first thing that needs to be done. When that works, write code that does the next thing that needs to be done. And so on. The trick however is to constantly review as you go along. Look for duplicated code, methods that are too long, classes with more than one responsibility. All that good design stuff.

When you notice something that isn't quite right, fix it. Fix it in the most minimal way possible. Duplicated code? Move to a method. Class doing two things instead of one? Split in to two separate classes. Resist the temptation to go beyond the most basic of refactoring. As your code grows, the refactoring will naturally get larger; introducing new modules, splitting out code to reusable libraries, reorganising namespaces, and introducing design patterns.

Or not. In fact I'd wager your code will be functionally complete long before you reach for any of the substantial design stuff. By writing code that does stuff first, you usually end up with less of it. Which is good, as it means you didn't need any of the big stuff. Less cognitive load, less room for error.

The code you write using this approach will usually be simpler. It may not let you show off your programming knowledge, or your skills as an architect, but it will function correctly and be maintainable.