Building a great user interface isn’t simple–but the result should be. No matter how complex the task is, your users should find it easy to figure how to use your application. Peter Vogel discusses two kinds of complexity and the strategies for making things simple.
Just because you’ve got a complicated program doesn’t mean that you need to have a complicated user interface. However, when your users have a complicated task, how are you going to present a simple and “easy-to-use” user interface?
A warning up front: The first thing to recognize is that “easy-to-use” is a relative term. What’s “easy-to-use” for me (a computer professional who spends as much time in front of a computer as away from it) is a complicated nightmare to my wife (who uses computers only when she absolutely needs to). If anyone tells you that you have a “great user interface,” you must recognize that what you have is a “great user interface” for that person–it could still be an absolute disaster for your actual users. As a result, I can’t guarantee that these techniques will work for your particular set of users. Caveat emptor!
Two kinds of complexity
Before you say that your application is complicated, you need to be clear what kind of complexity you have and what “complexity” means to your users. From the programmer’s point of view, there are two basic categories of “complicated user interface”:
- This user interface does a great many things.
- Carrying out some of the tasks in this application is complicated.
But this isn’t what “complexity” means to your user: For your user, “complicated” really means “I don’t know what to do next.” It really doesn’t matter how many or how few controls you have on your form: When your user always knows what to do next, then you have a simple user interface.
As an example, think back to the original user interface for complicated Web searches: A single button and a textbox for you to enter search criteria. How simple could you get? However, very few people used the advanced search features. That’s because the other feature on the page was a set of instructions that described how to enclose strings in double quotes, how to use the Not operator, how to “And” and “Or” tests together, and whatever other options were available. From most users’ point of view, advanced searches weren’t simple, no matter how few buttons were on the form. Or, to put it another way, the user didn’t know what to do next and, as a result, couldn’t use the advanced search features.
Divide and conquer
When you have a user interface that does a great many things, the primary principle for simplifying your user interface is “divide and conquer.” While your application does a great many things, you shouldn’t necessarily have to put all of that functionality on a single form. This shows up when a form supports creating several different kinds of objects.
For instance, imagine that you’re building a UI for a sales order system. In this application there are four different kinds of customers, five different kinds of sales orders, and four different payment methods. While these are all sales orders, you really have 4 x 5 x 4 = 80 different objects. A single form that supported all 80 objects would be a very flexible form. However, in order to support all 80 different combinations, you’d have a UI that couldn’t possibly tell the users what, exactly, they should do next for any particular combination of customer, sales order type, and payment method. From the point of view of both your users and yourself, this is a complicated form.
So, what can you do about this? The first thing is to ask your users. A quick discussion with users would probably reveal these kinds of scenarios:
- 80 percent of the orders involve one specific combination of sales order, customer, and payment plan.
- Another 15 percent of the orders involve supporting one other kind of sales order.
- The variety of customers is tied to the variety of payment methods: Each customer type uses only one of the four payment plans.
Rather than building a “do everything” form, you should build six forms:
- Four different forms to support the four different customer/payment plans but only handles the typical sales order.
- A fifth form that supports the second kind of sales order but only for the most typical customer and payment plan.
- A “do everything” form that would handle the “oddball” orders (probably less than 3 percent of the orders that go through the system).
This sounds like a lot more work than building the single “do everything” form. I won’t lie to you: It’s certainly more work than building a single “do everything” form. However, some initial planning to put common routines in class modules (or just publicly declared subroutines and functions) will allow you to reuse a great deal of the code. In addition, it wouldn’t be surprising to find the four different customer sales orders are really just the same form with a configuration routine that makes some controls invisible (and others visible) depending on which customer type is selected. Finally, testing and development will be much simpler for five simple forms than one complicated form.
You can even simplify your “do everything” form. Since this form is supposed to “do everything,” make it possible for the users to “do everything.” Build a form that lets the users enter whatever data they need with little support and very little editing. Because the form is only going to be used occasionally, you can specify that it’s to be used by one highly trained member of the user community.
Another kind of complexity doesn’t require the user to pick from a wide variety of different kinds of inputs. Instead, the form is complicated because it requires the user to decide which of many possible tasks to perform. For instance, there may be only one kind of sales order for all customers, but the sales order has different sets of information to be filled out, depending on what kind of payment plan is selected.
You could have a single form that supports every kind of payment plan but doesn’t help the user with any particular payment plan. Again, divide and conquer provides a solution. To support your user, you could create a tabbed form that has one tab for the sales order information, another tab for payment plan 1, another for payment plan 2, and so on. The user can fill in the sales order information and pick the tab for the correct payment plan, ignoring the tabs that aren’t necessary for this particular sales order. Each payment plan’s tab would be designed so that the user would always know “what to do next.”
The other kind of complexity that users face is a complex task: There’s only one object to create but a complicated series of steps that must be performed in a specific order, often with several decisions to be made along the way. Divide and conquer works here also. In this case, what you can do is break down your complex task into several smaller tasks and present each task to the user a piece at a time.
The most obvious solution is to create a wizard–something that’s not hard to do with Access (in fact, there’s a wizard for creating wizards, as was described by Garry Robinson back in our December 1999 issue). However, it’s possible to break complicated tasks down into a simple task with options.
As an example, in one application that I recently built for a client, a user needed to be able to assign a piece of equipment to a location in the plant. However, there were a number of possible scenarios:
- The equipment may already have been assigned to a location in the plant.
- The location may already have some equipment in it.
- The equipment may not exist (but the user could add it).
- The location may not exist (but the user could add it).
If the location already had a piece of equipment, it was possible to:
- Replace the existing equipment with the new one (effectively, putting the equipment already at the location back in the warehouse).
- Add the second piece of equipment into the location with the existing piece.
- Abandon the operation.
If the equipment was already in use at another location, there were only two choices:
- Remove the equipment from its original location.
- Abandon the operation.
I could have created a form that presented all of those options to the user at once–hardly a simple user interface. However, in analyzing the users’ scenario, I recognized that the most common activity would be to add a new piece of equipment to an empty location. So, the user interface I created allowed the user to perform that simple task. If, in processing the user’s request, I discovered that the equipment was already in another location, I would ask the user if they wanted to remove the existing piece of equipment (this required just a simple dialog box with Yes and Cancel buttons). Later, in the processing, I’d check to see if there was already some equipment at the new location. If there was, I presented the user with another dialog box with three choices: Replace, Add, and Cancel.
From the user’s point of view, this complex task had now become a simple one: Put the equipment at the new location. On some occasions, the users would be presented with a single dialog box asking them to make a simple decision or a single dialog box with a more complicated decision; on very rare occasions, they might be presented with two dialog boxes. However, even on the rare occasions when users were presented with both dialog boxes, they had only one decision to make at a time. And you can bet that I put as much helpful direction in those dialog boxes as I could to help the users make the right decision.
A case study: Tabs
I’ll be the first person to admit that it’s sometimes hard to spot which is the best way to break down a complicated activity. In fact, deciding whether you have a single object with lots of options or several different objects that look very much alike is probably a judgment call. And after that, should you break the task down by object or by sequence?
Making these decisions is tough. One tool that I mentioned earlier, the tab control, is misused often enough that it can be used to demonstrate the problem.
The most typical problem is when a developer uses tabs to sequence a complicated task: The user is to fill in tab 1, then fill in tab 2, then tab 3, and so on to the final tab. The best that can be said about this design is that it prevents the user from being overwhelmed with too much information at once. But if that’s the case, the user would probably be better off being presented with a wizard that would walk them through the task, step by step. Tabs shouldn’t be used to break down complex tasks.
However, once the object is created through a complex series of steps, a tab dialog can be very useful for managing complex objects. While a wizard might be the best way to walk a user through creating a sales order, after the sales order is created the user may need to go back to make changes. Rather than present the user with an overwhelming set of information, a tabbed dialog could break all the sales order information into simpler groups.
However, just because a tabbed dialog could be used doesn’t mean it should be used. A menu or a button to bring up a form that displays a single part of the sales order (for example, payment information) would break down the information as well as the tab dialog.
In fact, using a tab interface to break down a complex object only makes sense when a user typically needs to update two or more sections of the object and you can’t predict what sections the user will need to use together. In this very specific scenario, a tabbed interface would allow the user to switch between the sections quickly without having to return to a menu. As with dividing up the single “do everything” sales order form into five simpler forms, you need to know how your user is going to interact with your application to know what the right answer is.
So this article has three messages: Your user interface doesn’t have to be as complicated as your application. You can divide your user interface into simpler parts. And if you’re going to divide your user interface correctly, you need to know how your users are going to use your system. What could be simpler than that?