A Hierarchy of Needs for Code

February 28, 2008 ⋅ programming, design ⋅ 7 Comments »

A couple weeks ago, I trekked through another Toronto snowstorm all the way up to the Canadian Film Centre. Normally I’m a downtown snob and don’t go north of Bloor, but I made an exception this time because my friend Geneviève was demoing a project at the CFC Media Lab.

A Hierarchy of Needs for Design

While I was there, I happened across a copy of Universal Principles of Design. It’s a really cool book which describes 100 design principles: from general-purpose concepts like Ockham’s Razor and the 80/20 rule, to specific techniques like Iconic Representation (“the use of pictorial to improve the recognition and recall of signs and controls”). It’s kind of like a universal set of design patterns.

I only had a chance to flip through the book for a few minutes, but I really liked what I read. And Donald Norman recommends it, for what it’s worth.

One of the principles that I really liked was Hierarchy of Needs. Inspired by Abraham Maslow’s famous psychology theory, the authors proposed a Hierarchy of Needs for design:

A design must serve the low-level needs (e.g., it must function), before the higher-level needs, such as creativity, can begin to be addressed. Good designs follow the hierarchy of needs principle, whereas poor designs may attempt to meet needs from the various levels without building on the lower levels of the hierarchy first.

Design Hierarchy of Needs

What about the code?

This got me thinking about coding. As a programmer, you are designing not only the product itself, but also the code. For the end product (the software that you are producing) the Design Hierarchy of Needs can be applied. But what about the code? What would a hierarchy of needs for code look like? Here’s what I came up with, but I’d like to hear what everbody else thinks.

Keep in mind that this is a hierarchy of importance, with the lower levels being more important. It’s most definitely not a sequence of steps.

Hierarchy of Needs for Code
  • Functionality: If your code doesn’t work, there’s no point in optimizing that inner loop, or refactoring it to be infinitely flexible.
  • Reliability: Any software developer worth his salt knows that there’s a big difference between code that “works”, and code that is ready to be shipped. After your code is functional, you need to make sure that it is reliable. Run it through your unit tests, run it overnight, run it on grandma’s computer.
  • Maintainability: Can other people understand the code? Can you understand the code? When bugs are discovered, you need to be able to fix a bug and be confident that you won’t be causing more bugs in the process.
  • Extensibility: Is your code adaptable to meet new requirements? If your code is extensible, you will be able to grow and adapt your software to meet the changing needs of your customers. If not, you might have to throw it out and start from scratch.
  • Elegance & Efficiency: If you are sure you are meeting the other levels of need, then and only then should you worry about making your code fast and beautiful. Unfortunately, many people get hung up on this level instead of focusing on the more basic needs.

What do you guys think? Anything you’d change about it?


Related: Andrew McKinlay wrote about A Programming Hierarchy of Needs, and Oliver Steele proposed The Programmer’s Food Pyramid. Kathy Sierra, whose blog Creating Passionate Users I sadly miss, also tackled the user hierarchy of needs, and asked What comes after usability?


7 Comments:

  1. e - February 28, 2008:

    I would add a layer below functionality, titled "Honest Libraries."

    Code has to behave the way you expect it to. There are very few scenarios where a programmer is building from the metal up. If you're relying on anyone else's machinery, that machinery has to behave the way you expect it to. If code is too complex to understand quickly, it needs documentation. If there is documentation then it has to be accurate, and provide a rough idea of what the code actually does.

    I wouldn't separate functionality and reliability. If there are (say) threading issues in code, but it works well 95% of the time, it isn't functional.

  2. سردال » ملخص 28 فبراير - February 28, 2008:

    [...] إذا كان هناك هرم لاحتياجات الإنسان النفسية فهل هناك هرم للبرمجة؟ [...]

  3. Patrick - February 29, 2008:

    e:

    Code that behaves as expected is obviously important, as is documentation. I think this falls outside of this hierarchy though; the library code should also be built according to the hierarchy, and the "honesty" you're talking about is really the functionality of the library. And documentation doesn't really seem to have a spot in this hierarchy...not sure where it should go.

    I agree that the line between functionality and reliability is a fuzzy one, but certainly there is software that "works" while not being especially reliable. For example, I don't think it's correct to say that Windows 95 wasn't functional -- it just wasn't particularly reliable. Likewise, I've tried lots of programs that do the job they were intended to do, but choke on any unexpected input.

  4. Mark - March 7, 2008:

    I think depending on the application that any of maintainability, extensibility and efficiency could be in a different order. eg. A lot of games programming is barely extensible but highly efficient.

  5. Nick - March 29, 2008:

    Although the program itself needs to have the lower part of the hierarchy to work, the algorithm behind it needs to be elegant and efficient, especially if it cannot be changed after the program is written. I would put elegance and efficiency below maintainability and extensibility.

    It really should be looked at where each aspect is as dependent as possible on the ones below it. You need it to function above all, then you need it to function well (reliability/efficiency), then you need it to be useful and flexible to others (maintainable and extensible).

  6. Patrick - March 30, 2008:

    @Nick:

    You think that efficiency and elegance is more important than maintainability and extensibility? If it's maintainable and extensible, then you can always fix it to make it faster. I think it's better to have a well-written and well-documented library in Python than to have a blazing-fast assembly language implementation.

    As for elegance, I think that if code is maintainable and extensible, it has no need to be "elegant".

  7. dan - November 11, 2010:

    I would agree with Mark that it depends on the application. For many apps, the 'quality' of the code is evaluated by performance more than by maintainability or extensibility (games, profilers, databases, video rendering, etc.). For most business apps, however, I agree with your hierarchy.