What are You Looking At?


[Obnoxious, snotty narrator begins]

"....When last we left our heroes at Munstris Diveloperz Inc., they were left wondering how applications can be made truly simple. Some software just worked well and other software just seemed bad, but they couldn't figure out why. It seemed like finding a good software tool was no simpler a task than navigating a vast digital jungle with little more than a pocket knife while wishing for a razor-sharp machete. As digital carpenters, the development team needed a good whack with a Clue-By-Four™ or face being left pretty much to the same shoddy equipment as everyone else. The management just needed a good whack."


---------> We pardon the interruption. The people responsible for this irresponsible attempt at sophomoric humor have just been sacked. <-----------

— Management

Seeing Clearly

What our poor developers in the above scenario were missing is focus. While we developers are used to getting into "the zone" and flinging code that (mostly) works way it should, this is not the kind of focus to which I am referring. When developing an application, the main thing that must not remain as the sole focus is the technology. Technology is the means to the goal. Should we focus on the cool stuff we can build into software, we lose sight of what it is ultimately supposed to do — just like running a marathon while staring at your feet, one tends to not see problems until one quite literally runs into them. What is the goal? The ultimate goal is to write good, fast, stable software which does exactly what it is supposed to do — and nothing else — while making it accessible to the intended type of person, and only one person of that type. Who is this person? It depends on the type of application, and an application's target audience will be discussed in detail! ! in the next article. In order to write a good application, some forethought is required before flinging code.

The Process

<*spit*> Just the name disgusts me, because the first thought it brings to mind is a bureaucratic fad which doesn't work and (hopefully) dies a relatively quick death in the department after a short time of decreasing productivity. The task at hand could better be termed "look before you leap," and it doesn't really take much time or effort.

First, describe the entire application's concept in a sentence. This could simply be something like, "The goal of this project is to create a front end to cdrecord which gives the user the ability to burn music and data CDs with a minimum of fuss." Second, come up with a list of tasks the user will commonly perform with the application, such as "Add an MP3 to an audio project." We can call these tasks "primary tasks" for the sake of reference. Next, brainstorm a list of tasks which the user may have a need for on an less frequent basis — secondary tasks. The number of secondary tasks should not greatly outnumber the number of primary tasks. The reason for this is to gear the application primarily toward the tasks which are most likely to be needed. Now that it is relatively clear what the application is supposed to do, it is time to consider the implementation.

When considering the implementation of the application, we don't need to genuinely consider the nasty details — just the generalities — and only doing this to get a rough idea of how the application will work. Continuing with our example, we just could say that when we add a track to a music CD project, we'll verify that the file is a sound file and add it to the track list. One thing to note is that not only has no code been written, no consideration has been given to what the front end will look like, either. This is next.

Designing the interface is perhaps the most difficult part of designing an application because a great number of considerations must be made. Even when one writes a command-line app some thought must be given to this, albeit less than for a GUI app. For the purposes of these articles, we will limit our focus to the GUI. An interface should be unnoticed if constructed well. A quote from Albert Einstein also applies here: "Things should be made as simple as possible, but no simpler." In the same manner, here is a list of good rules of thumb to design by:

  1. Whenever possible, make commands undoable.
  2. The interface should not reflect the implementation in its design.
  3. In terms of features, be concerned with what the user is likely to need.
  4. Use everyday language — avoid computer terms whenever possible.
  5. Use controls for the tasks and in the manner for which they were designed.
  6. Control layout should have a logical or natural order.
  7. Make errors nearly impossible, if not impossible.

From a perspective which focuses on technology, humans are imprecise, illogical, disorganized, and they frequently make mistakes. God also created them to be good at matching patterns and at creating habits. Being able to undo a command suddenly makes the software forgiving, and the user is allowed to explore without worry of causing irreparable harm. Windows is infamous for asking the user "Are you sure?" when sending an item to the Recycle Bin. The Recycle Bin itself is good because it is possible to restore a "deleted" file. The confirmation dialog is useless because the user will habitually click 'Yes.'

The interface should not reflect the way an app is implemented because doing so often overcomplicates the interface. There are quite a few BeOS apps which are little more than front ends to mp3 encoding programs like lame and bladeenc, for example. The reason for their existence is because the encoders are command-line applications with many, many options, which reflects, in a sense, the way that they were written. These front ends should — and often do — reduce the great complexity of these encoders to the options which most users need to encode MP3 files.

Software which includes every feature save the kitchen sink is an excellent example of hubris and the wrong perspective. For example, I have a 6-in-1 tool I was given for Christmas. In combining so many tools, such as a hammer, wrench, pliers, etc., it unfortunately doesn't do any of them very well. Given a personal choice among Word, WordPerfect, Works, and Productive for Windows, I choose Productive because it offers the word-processing features I need without requiring me to hunt for them among features that I either don't understand or will never use. The common practice is to think "well, the user might need to do this." It is most often better to have smaller, specialized tools than one tool which does it all.

One of the qualifications for a field to be considered a profession is that the field has its own body of knowledge with its own technical terms. The computer field is no different. Using these terms in an application is appropriate only if the software is intended only for developers. Most often it is not. Helios, for example, is a good BeOS cdrecord front end, and does a good job of simplifying the task for which it is designed. However, a perusal of the preferences window yields some panels with checkboxes and radio buttons whose function remains a mystery to me.

Graphical controls are largely used the way they should be, but not always. This UI Hall of Shame shows some good examples of what *not* to do. Edit boxes should not be used in place of labels. Buttons should not be used as toggles — that's what checkboxes are for. Tabs should not imply a mode based on which one is active. A group of checkboxes should not be used for a group of radio buttons, which are designed to choose one from a number of choices.

Likewise, controls should be presented in a natural order. The edit boxes in the People application are ordered in the same manner as an address would be listed. Random or illogical control layout presents a hurdle to the user by forcing the user to think in a flow different from the natural order or exert unnecessary effort to move between the controls to maintain the natural order of thought. Interfaces need to let us work smarter, not harder.

Error messages are all too common, especially those in dialog boxes. If a developer can foresee an error condition, it needs to be compensated for. Does a directory not exist when it should? Create it. Can't find a file where it should be? Query for it. Only when software runs out of options in compensating for error conditions should it tell the user, and even then, the error message should be as non-technical as possible and also helpful, informing the user what course of action should be taken to remedy the problem. Crashes should not happen. Period. The error compensation in software sometimes requires considerable work, but it is worth it.

Human-computer interaction is a complicated subject and there are Masters degrees in the field, but designing good software does not have to be quite so difficult. It merely requires us developers to change the way we think. The more I work with software, the more frustrated I get because the software is bad and doesn't have to be this way. When I run, I prefer to keep my eyes on the goal. How about you?