August 5, 2012

...Learn TDD with Codemanship

Back To Basics #8 - Interfaces Are For Communicating

This is the eighth of ten posts setting out basic principles for software development without all the usual hype and buzz that tends to leave younger developers under the mistaken impression that we've only very recently figured this stuff out.

Basic Principle #5 states that the principal activity in software development is communicating

The interfaces we design to allow people - and other software - to use our programs fall under that banner, but I feel they're important enough to warrant their own principle.

An interface provides a means for users to communicate with our software, and through our software, with the computer.

There are different kinds of interface.

Most computer users are familiar with Graphical User Interfaces. These present users with friendly and easy-to-understand visual representations of concepts embodied by the software (like "file", "document", "friend" and so on) and ways to perform actions on these objects that have a well-defined meaning (like "file... open", "document... save" and "friend... send message").

Other kinds of interface include command line interfaces, which allow us to invoke actions by typing in commands, web services which make it possible for one program to issue commands to another over the World Wide Web, and application-specific input/output devices like cash registers used by shops and ATMs used by bank customers.

When we view interfaces as "things users communicate with the software through", it can help us to understand what might distinguish a good interface design from a not-so-good one, if we contemplate some basic rules for effective communication.

Interface design is a wide topic, but let's just cover a few key examples to help illustrate the point.

Firstly, effective communication requires that the parties talking to each other both speak the same language. A Graphical User Interface, for example, defines a visual language made of icons/symbols and gestures that need to mean the same thing to the user and the software. What does that picture of a piece of paper with writing on it mean, and what does it mean when I double-click on it?

An important question when designing interfaces is "whose language should we be speaking?" Should the user be required to learn a language in order to use the software? Or should the software speak the user's language?

Ideally, it's the latter, since the whole point of our software is to enable the user to communicate with the computer. So an interface needs to make sense to the user. We need to strive to understand the user's way of looking at the problem and, wherever possible, reflect that understanding back in the design of our interface.

Interfaces that users find easy to understand and use are said to be intuitive.

In reality, some compromise is needed, because it's not really possible yet to construct computer interfaces that behave exactly like the real world. But we can get close enough, usually, and seek to minimise the amount of learning the end users have to do.

Another basic rule is that interfaces need to make it clear what effect a user's actions have had. Expressed in terms of effective communication, interfaces should give the user meaningful feedback on their actions.

It really bugs me, as someone who runs a small business, when I have to deal with peoople who give misleading feedback or who give no feedback at all when we communicate. I might send someone an important document, and it would be very useful to know that the document's been receieved and that they're acting on it. Silence is not helpful to me in planning what I should do next. Even less helpful is misleading feedback, like being told "I'll get right on it" when they are, in fact, about to go on holiday for two weeks.

If I delete a file, I like to see that it's been deleted and is no longer in that folder. If I add a friend on a social network, I like to see that they're now in my friends list and that we can see each other's posts and images and wotnot and send private messages. When I don't get this feedback, I worry. I worry my action may not have worked. I worry that the effect it had might be something I didn't intend. Most annoyingly, because I can't see what effect my actions have had, I struggle to learn how to use an interface which is perhaps not entirely intuituive to me.

An interface that gives good immediate feedback is said to be responsive. Value responsive interfaces as much as you value responsive people.

Which leads me on to a third basic rule for interface design. Because it's not always possible to make interfaces completely intuitive, and because the effect of an action is not always clear up front, users are likely to make the occasional boo-boo and doing something to their data that they didn't mean to do.

I remember years ago, a team I joined had designed a toolbar for a Windows applictaion where the "Delete" button had a picture of a rabbit on it. Quite naturally, I clicked on the rabbit, thinking "I wonder what this does..."

Oops. Important file gone. In the days before the Recycle Bin, too. The one button they didn't have was the one I really, really needed at that point - Undo!

Interfaces that allow users to undo mistakes are said to be forgiving, and making them so can be of enormous benefit to users.

There will be times, of course, when an action can't be undone. Once an email is sent, it's sent. Once a bank payment is made, it's made. Once you've threatened to blow up an airport on a public forum, and so on and etc.

When actions can't be undone, the kindest thing we can do is warn users before they commit to them.

Another way we can protect users is by presenting them only with valid choices. How annoying is it when an ATM prompts you to withdraw £10, £30, and £50, and when you select one of those options you get a message saying "Only multiples of £20 available". Like it's your fault, somehow!

Interface design should clearly communicate what users can do, and whenever possible should not give them the opportunity to try to do things that they shouldn't. For example, a file that's in use can't be deleted. So disable that option in the File menu if a file that's in use is selected.

Similarly, when users input data, we should protect them from inputting data that would cause problems in the software. If the candidate's email address in a job application is going to be used throughout the application process, it had better be a valid email address. If you let them enter "wibble" in that text box, the process is going to fall over at some point.

Interfaces that protect the user from performing invalid actions or inputting invalid data are said to be strict. It may sound like a contradiction in terms to suggest that interfaces need to be strict AND forgiving, but it's all a question of context.

If, according to the rules of our software, there's no way of knowing that the user didn't intend to do that, then we need to be forgiving. If the rules say "that's not allowed in these circumstances", then we should be strict.

One final example, going back to this amazingly well-designed GUI with the rabbit Delete button. On the main toolbar, it was a rabbit. But there was also a Delete button on the individual File dialogue, which sported a picture of an exclamation mark. So having figured out once that "rabbit = delete", I had to figure it out again for "exclamation mark = delete". Boo! Hiss! Bad interface doggy - in your basket!

We're bad at this in our industry generally. We tend to have various different terms that all mean the same thing. And it makes learning much harder, and communicating with each other potentially hazardous.

In physics, they resolved to be very, very careful about their use of language when it mattered. To a physicist, terms like "dimension" and "energy" have very precisely defined meanings, so when physicists explain their theories, we're less likely to misinterpret.

They're not quite so strict about their use of language in, say, alternative medicine and New Age philosophy, where terms like "dimension" and "energy" can mean pretty much anything we want them to mean.

I'm sad to report that, in our use of language, software development is as bad as New Age philosophy, with commonly used terms like "Agile" and "test-driven" taking on many different meanings.

Two teams could both be claiming to be "Agile", but working in remarkably different ways. So when a developer learns about "Agile Software Development" working for one company, they may come to realise that what they've been doing is considered not "Agile Software Development" to teams at another company.

Imagine if you learned physics at Cambridge, but when you applied for a job at CERN, they told you "no, that's not physics as we understand it"...

Anyway, moan moan grumble grr etc.

My point is this, in order for us to communicate effectively we must not just be clear, but also consistent in our use of language. When we're inconsistent (e.g., "rabbit = exclamation mark = delete"), we significantly increase the amount of learning the user has to do.

When designing interfaces, we should also remember Basic Principle #3 - Software Development Is A Learning Process. It's vanishingly rare to find teams who get it right first time. We should iterate our interface designs frequently, seeking meaningful feedback from end users and the customer and allowing the design to evolve to become as intuitive, responsive, forgiving, strict and consistent as it needs to be to allow users to get the best from our software.

There is, as I said, a whole lot more to interface design than this, but hopefully this gives you some flavour. In particular, we need to remember that good interface design is about effective communication.

Posted 8 years, 7 months ago on August 5, 2012