I’ve been dealing with bugs a lot, lately. Not the living insect variety, but the computer bug sort. It is my job. Yes, I’m a missionary, and I do “missionary-like” stuff like living in a remote area in an exotic nation, preach in another language, and continually have faith in God to supply the needs of my family, my ministry, and myself, because I get no salary. My 40-hour-a-week job, though, is IT support and custom programming for a mission aviation organization with 7 aircraft. I support Bible translation work by supporting the people who get the Bible translators in and out of their villages, and who keep supplies coming in a land with very few roads.
In combating computer software bugs, I have learned to recognize some really common ones. I have also learned some things about writing software to avoid them. Just like bugs in the animal kingdom, there is a taxonomy that can be used to describe them. One major distinction is the source of the bug: bad design, bad implementation of a good design, or both. The bad implementation side is the one people usually focus on. I have seen several lists of common errors, like stack overflows, arrays with indexes out of bounds, improper validation of input (especially if that input is going to be interpreted by another process like a SQL server), etc. Such things are important to pay attention to, but those are like miller moths (the kind of bug found in a relay of one of the first computers, and for which all computer bugs are named). They can’t bite you, don’t normally carry diseases, and as long as you keep them from laying eggs in your stored clothing or wedging their bodies into your relays, it takes a lot of them to really do much damage. Design problems, however, are more like centipedes, scorpions, and poisonous spiders. They can be lethal to a project.
One particular design problem that I have seen too much of is in the form of bad user interface design. Human interaction with machines is very complex, because humans are extremely complex and the machines they use tend to be a little complex, too. I enjoy the computers on Star Trek, because they are so speedy, recognize natural speech in almost any language in the galaxy, can store the collected information from multitudes of civilizations and search and analyze it all in seconds, and can produce any kind of food or beverage on command. They always seem to just understand what the user wants. Not so with the computer I’m typing this article on. I could name at least two projects that had serious user interface (UI) problems in the world of Bible translation and Bible translation support software, but I won’t, at least here. One of those is basically irrelevant except as a how-not-to lesson, as it is essentially dead, killed by lack of use. The other has credible hope of being resurrected with a UI make-over in at least the most critical areas.
Rather than detailing all that is wrong with the UI designs I have seen, I prefer to be a little more positive, and focus on what is good and right about the best UI designs that I have seen. Here are some things to keep in mind when designing a new program or program suite that may save you some grief:
- Before writing a single line of code, design at least the basics of the user interface. What are the inputs, outputs, and interactions? How do they fit with the work flow of your customers? Is this the same as what they do, now, or better? (If it is not the same or better, then scrap the idea and start over.) To really do this right, you need a good understanding of what problem(s) you are trying to solve, and good lines of communication with your customers. (Yes, you have customers, even if you write free software.)
- Know your customer base. Know their education level range, their familiarity with computers, other programs, and operating systems. Know what kinds of computers they use and are likely to use. Know why they would want to use your new and/or improved program. Talk with them frequently before, during, and after design and development of the program. If the entire user base is too daunting and could consume all of your time, talk to a few truly representative users, and make some way for others to send feedback (i. e. bug reports, feature requests, etc.).
- Make your UI intuitive. That means make it so obvious how things should be used that someone who has never used it before can use it. In reality, the only way you will get this done is to copy the good ideas and behaviors of other common programs that users have likely used, before.
- Read up on good UI design. Microsoft and GNOME both have good things to say in this regard. Even if you don’t like all of their ideas, you need to use most of them or your interface will seem strange to people, because it is different.
- Use a good UI design toolkit/library. Not only does this save you from “re-inventing the wheel,” it makes it easier to both be consistent and be more like other programs (and therefore more intuitive).
- Do not get too “creative” with your UI. Sometimes even something that is arguably better is much less intuitive, because people aren’t expecting whatever you are throwing at them. Choose a “normal” way of doing things. Read Microsoft’s Common User Interface guidelines and the Gnome project’s user interface guidelines for some good ideas that you should probably stick to unless you have a good reason not to.
- Match the UI to the task. For example, if it is a control system for a physical system with fluid or material flows, lay out your UI in an easy schematic diagram of that system. If is a calendar, make it look like one. If it is a recipe book, make sure it is easy to find the recipe “cards,” and once you present them, they look like what cooks are used to seeing. If it is a flight simulator, make it look like a cockpit. I once visited a business web site that was programmed like a video game, but the business had nothing to do with video games. Match the form to the function.
- Make the common stuff easy to do and easy to find. Minimize the number of mouse clicks and keystrokes it takes to do stuff that is done frequently.
- De-emphasize the more esoteric or “advanced” stuff, lest it confuse the beginners and casual users of only the basic functions.
- In de-emphasizing the advanced or infrequently-used features, take care not to hide things too well. Make such things reasonably obvious to find, too. Sometimes it is better to have a larger set of options shown at once, and sometimes you need to show just a few. Knowing when to do which is a matter for experience and wisdom. Usually, this balance has to do with putting “advanced” features on a separate dialog box, or having a less/more button on a dialog box. It also explains the partially-hidden menus in some programs, although I never liked that feature myself. So, if you do that, make sure the users that are annoyed by that can turn the menu-hiding off.
- Be consistent. This includes layouts of dialogs (i. e. normal locations of OK and Cancel buttons) as well as when and how things get saved. Some programs automatically save everything you do instantly, with no “save” button needed, but some require an explicit “save” function. Try to do it the same way within the same program.
- Give the user good feedback. When something happens, make it look like it happened. Users are ALWAYS confused if you don’t do this. Better yet, give feedback of exactly what happened, visually, audibly, or both. Make it obvious what is going on.
- Provide an “undo” function where appropriate. People goof. Often, they recognize immediately that they goofed (especially if you give good feedback), and they want a way to repent, undo, and avoid disaster. Make it possible.
- “Are you sure you want to launch a nuclear missile?” messages are no substitute for a good undo function. Choose wisely where you put “Are you sure?” prompts, and don’t over-use them. Otherwise, they will be ignored when they are really needed.
- Avoid overusing modalism, or the shifting of controls into different modes. Computer interfaces are inherently modal. Different menus, buttons, controls, etc., appear on your screen at different times in different situations. This is both flexible and annoying. It is both powerful and non-intuitive. Consistency is intuitive and easy. Consider the automobile. The accelerator pedal is on the right. The brake is to the left of it. Turning the steering wheel clockwise turns the car to the right when moving forward. It is always the same, in all cars, all over the world. I like that. When practical, keep the same kinds of controls in the same places.
- Keep it SIMPLE! This is probably the most important suggestions. It takes careful balance. Don’t bedazzle & befuddle the user with too many things at once, but don’t make it too tedious to find all of the things that the user wants to do. Group things together that logically go together in the user’s normal work flow.
- Make the program forgiving. I detest programs that you have to press 3 buttons exactly once, in order, exactly one time per month, or things get messed up. If one of the buttons doesn’t work, programmer intervention is required. Don’t do that. If a button can be pressed, make it do something safe and useful. If not, disable or hide it. If something has to be done exactly once a month, reconsider the design.
- Write clear, concise, indexed, illustrated instructions. If you can’t write well, find someone who can to help you. Include the instructions with the program and keep them up to date with the program.
- Keep the design of the over-all program simple. If you have trouble explaining to someone how to use it, chances are that it really is too hard to use, and needs to be changed.
- Keep the number of controls to the minimum needed to accomplish the task efficiently. Remember that for each control you add, you raise the minimum I. Q. of the operator by 3 points.
Now I’ve reminded myself of what I’m shooting for as I redesign some software. I hope it helps you, too.