Art and the Zen of
system design
by Tony Karp

There are many different kinds of systems. Some are built around computers, some are built around people, and some involve interaction between a person and a machine. Some systems, like the Internet, are huge. Some, like a pocket calculator, are quite small. History is filled with the tragedies wreaked by systems gone awry, but at their finest they can put a man on the moon.

For all of these, there will be a process of system design and architecture. The items listed below take philosophical view of the design process, rather than a technical one.

You can just read the list from start to finish, but you might find it more interesting to pick one item at random and reflect on how it might relate to the systems you're working on.

"This is just the sort of thing that this kind of thing has always been an excellent example of."
- Vincent van Gui

"First, do no harm."
- attributed to Hippocrates

0. Identify and determine who will be the actual users of the system, and learn as much as you can about them.

1. Find what the user does most often and make this the easiest thing to do on the system. (This viewpoint is different from the "Make difficult things easy" viewpoint.)

2. Find the actual job that the user is doing and make it easier to do that job.

3. Design your system so that no error messages are required. The ideal system will not require error messages because there is no way for it to be misused. Keep this ideal in mind as you work.

4. Make it so that the user only has to understand their job in order to use your system. Be wary of designs that require extensive user training.

5. If the users persist in misusing the system, change the system, not the users.

6. Try and anticipate what the users will do wrong and make your system handle it gracefully.

7. Build in logging, diagnostics, performance measurement, and troubleshooting tools as part of the design.

8. Live with the users and try to understand their jobs, their environment, and how they will use your system.

9. Try and build in DWIM and instinctive responses, so that the system appears to anticipate the user. DWIM comes from a statistical understanding of how the system is actually used. (DWIM = Do What I Mean)

10. Every action by the user must produce a reaction from the system.

11. Consistency is the key to interface design.

12. Users develop habits. You can take advantage of this to make things easier or you can use it to drive people crazy.

13. When choosing the components for your system, try to use ones that are standard, simple, well understood and well documented.

14. Start from a small, simple, well-understood point and evolve upwards from there, making sure that you learn as you build.

15. Keep it simple. There's always time later to make it wondrous and complex.

16. Don't reject a solution just because it doesn't solve 100% of the problem. This may be an impossibility, and is a favorite tool of the naysayers and quibblers.

17. Make it easier to use the system than to not use the system.

18. Don't hide things from the user. Put everything right out front.

19. The designers should be the first real users of the system. They will immediately see what works and what needs changing.

20. Don't use new technologies just for the sake of it. Use older, well-understood, well-supported technologies.

21. Overestimate. Designers tend to underestimate time and resources needed. Promise late -- deliver early.

22. Design and build in a series of small steps, each one understood and approved by the user before going further.

23. Learn how to model a system before building it.

24. Learn how to build and use tools.

25. Be prepared to change direction if you run into a wall.

26. Don't treat the users as outsiders. Treat them as partners and give them a sense of ownership in the system. If they feel it really belongs to them, they will defend and protect it.

27. Be ready for sabotage and try to deal with it quickly and quietly.

28. Learn how to automate the maintenance process.

29. Look for non-linear solutions that solve a problem by restating it.

30. Consider the use of domain-specific languages that allow non-programmers to define a problem solution in terms of their expertise.

31. Design statistics gathering into your system -- not to have a bunch of numbers to impress the vice presidents, but to learn how people are actually using your system. Then go back and look at item #1.

32. Learn how to parameterize your system. This will make it easy to maintain and modify.

33. Learn how to work within the existing standards and use them to your advantage rather than fighting them.

34. Study the pathological operation of your system. What can go wrong? How will it be discovered and reported? How will it be fixed?

35. Don't panic.

Copyright 1957-2019 Tony & Marilyn Karp
Originally posted October 4, 2002