Five Design Skills Every Programmer Should Have

There are some basic capabilities I would like every programming student to learn in school:

  1. Given an existing, large program, determine what its most important classes are, what they're responsible for, and how they relate to each other.

  2. Given a program, identify duplication and other design smells that make arbitrary change difficult, and come up with a list of incremental, behavior-preserving refactorings that will solve those problems and can be implemented gradually, over time.

  3. Given a program and a list of feature changes, determine what parts of the program should be changed to support the new features and, if the program design doesn't support the new features cleanly, what incremental refactorings will improve the design so that it will.

  4. Given a blank slate and a list of features, use test-driven development to create new code that is tested by unit tests that meet Michael Feathers' definition of "unit test."

  5. Given a blank slate and a list of features, incrementally mix design improvements with new feature development on a daily basis, without utilizing multi-day "design" or "refactoring" phases.

I see these as foundational skills that any programmer could learn and that every programmer should have. I would expect that programmers fresh out of college would be fairly slow at these things and would need help applying them, but they should have shown the ability do all five of these things on some problem somewhere. Then, with experience, they would learn how to apply these skills more broadly and more quickly.

Too much to ask? I don't think so.

If you liked this entry, check out my best writing and presentations, and consider subscribing to updates by email or RSS.