My name is Jack Moffett
. I am an Interaction Designer with over ten years of experience. According to Herb Simon
, that makes me an expert, so I must have something worth sharing. I have started this venture as an exercise to spur critical thinking about my chosen profession. I hope that others may find it thought provoking as well.
DesignAday will present a brief thought about Design every weekday.
Eric Raymond’s Rule of Extensibility advises us to “Design for the future, because it will be here sooner than you think.” And while he was referring to data formats, protocols, and software architecture, the rule applies just as well to the design of the user interface. The first version is only the first version. Future releases are going to sport additional features. Design your navigation so that you can add additional destinations. Lay out your bars and palettes such that you can add additional tools and settings. Design for growth, so your application doesn’t resemble a patchwork quilt a few versions down the road. When you have a well-designed UI, it is generally obvious where and how a new capability should be integrated. It will make sense, because the concept underlying the design makes sense. Document your design as a guide for those that may work on the product after you, as well as for your own reference.
This concludes my series based on Eric Raymond’s unix design rules. To see all posts in the series, visit DesignAday Unix Design Rules.
Eric Raymond’s Rule of Diversity admonishes us to “Distrust all claims for ‘one true way.’” In the world of software engineering, the intent is to promote open, extensible systems, but the same rule can also be applied to Interaction Design. In fact, there are multiple ways to skin this particular cat.
One of the keys to a healthy design process is to have a diversity of ideas. The first solution that comes to mind is not necessarily the best solution. Even once a direction has been decided, stay fluid as long as possible, allowing changes based on iterative prototyping and user feedback.
Designers utilize a diversity of methods depending on the context of the problem space. A good designer will adapt her process to match the specifics of a project, rather than doggedly forcing every project through the same sequence of tasks and deliverables.
User interfaces for complex applications provide multiple means by which to accomplish a task. Menu bars, tool bars, and contextual menus may all provide access to the same functions, but cater to the needs and expectations of different users. Search, advanced search, filtering, and faceted navigation can all lead a user to the same item, but are intended for differing approaches to the content. And there are multiple means by which to notify users of events within the system, each one optimal for certain situations.
Diversity allows for optimized processes, innovative solutions, and rich interactions.
Eric Raymond’s Rule of Optimization implores us to “Prototype before polishing. Get it working before you optimize it.” As with most of the Unix design rules, this one doesn’t only apply to writing code. When designing a user interface, it is imperative that one explore multiple solutions through sketches, mockups, and prototypes before setting the design in code, or even in a specification. Ideas can be fleshed out much more quickly on paper than in pixels, and a partially functional prototype can help make important decisions before a lot of effort is spent on implementation.
Eric Raymond’s Rule of Generation encourages programmers to “Avoid hand-hacking; write programs to write programs when you can.” Of all the Unix design rules, this one may be the hardest for me to reconcile with interaction design.
Ever since I was in graduate school, I’ve had major reservations about toolkits. Everything I’ve seen that was designed to make a coder’s job easier does so at the expense of the user experience. I witnessed a major project nearly run into the ground because a subcontractor decided to rebuild a suite of applications in Eclipse. I’ve been forced to use free, 3rd party widgets only to find that they are too limited to actually do the things we were hoping to do with them. Show me a web application built with GWT that doesn’t look like it was built with GWT.
That said, I’m all for creating a library of UI design patterns that can be applied across products. As you create features, work with the developers to componentize them so that they may be used easily elsewhere. Document them so that there is a record of their existence and instructions on their use, and then advertise them within your company’s development groups.
Eric Raymond’s Rule of Economy states “Programmer time is expensive; conserve it in preference to machine time.” But I’ve got a better one.
The user’s time is precious; conserve it in preference to programmer time.
It’s so easy for a development team to make decisions based on the schedule, rather than based on what’s best for the user. We have to deliver on schedule. We have to deliver within budget. But think about this. An implementation that saves a developer an hour or two may require one extra click from the user. That doesn’t sound so bad… until you realize that the user must perform that extra click fifty times a day. And it’s not just that user. There are thousands of them. The impact on productivity could be quite profound over the life of the product. If you think I’m exaggerating, consider the amount of web developer time that has been burned hacking IE 6.
Eric Raymond’s Rule of Repair states “Repair what you can—but when you must fail, fail noisily and as soon as possible.” There are several key points to take away from this one.
- Repair what you can. To the extent possible, design software that will cope with unexpected conditions and self-correct. In the ideal case, a “failure” will be handled by the system without any need to notify the user. Of course, if the system handles the problem itself, it isn’t really a failure.
- Fail noisily and as soon as possible. When a true failure does occur, make sure the user knows about it immediately. For example, in a technical manual, applicabilities filter content so that only the information that applies to a specific piece of equipment or condition will be displayed. If the instantiation of applicabilities fails, a technician could be presented with procedural steps that result in damage to the equipment or even personal injury. Such a failure should be made known without any chance of it being missed.
- Tell the user what happened. Rather than just displaying an error code or a generic message, give the user an explicit, understandable explanation of the failure. By understandable, I mean in terms he or she will understand—not dev speak. In the above example, the message might be, “Warning: The selected applicabilities failed to filter the manual. Any information displayed may not apply to the current situation.”
- Tell the user what to do next. The fact that an error occurred is of little use unless the user knows what to do about it. Any error message should not only explain what is wrong, but how the user should proceed. In many cases, the instruction may simply be to contact the system administrator, but their may be times that restarting the application or refreshing the browser will solve the problem and allow the user to continue.
- Make diagnosis as easy as possible. Regardless of whether or not the user will be troubleshooting the problem, provide the information that will hopefully lead somebody to the cause. This is where error codes and strange messages about databases and Java files come into play.
One of my current tasks is to go through all of the error messages in an application we are developing to make sure they follow these rules. It isn’t going to be very enjoyable work, but it is going to make for a better product that will hopefully be easier to support.
Eric Raymond’s Rule of Representation doesn’t translate directly to a rule for interaction design, but allows a corollary.
Fold knowledge into data, so program logic can be stupid and robust.
The point is that fairly complex data structures are more easily modeled and understood than procedural logic. Since that is the case, it makes sense to move complexity from the code to the data. The corollary, then, is to move complexity from the UI to the code whenever feasible. Certainly, for an application to be useful, there will be some level of complexity that is necessary. The user will have to make certain choices and take certain actions. However, there are many cases in which some extra work behind the scenes will save a user time, reduce mistakes, or make a task easier. The hour spent by a single developer in implementation may save weeks of productivity when hundreds or thousands of users are taken into account.
Eric Raymond’s Rule of Silence states that “When a program has nothing surprising to say, it should say nothing.” This is arguably one of the simplest Unix design rules to understand, and it is obviously a good rule to apply to any software, regardless of the underlying architecture. That said, it is surprising how often the rule is broken. From updaters that feel it necessary to inform you that there are no updates available to webpages that make you click to see whether or not a section actually contains content, the user interfaces we interact with daily are littered with examples of unnecessary communication.
- When functions aren’t available or areas of the interface contain no useful information, disable them, both visually and behaviorally.
- Don’t interrupt the user with modal alerts unless it is critical that you get their attention. There are subtler ways to communicate that don’t get in the way.
- Use audio sparingly.
- The visual design should direct attention in a sensible way. Don’t distract the user with bright colors and high contrast unless there is a good reason to do so.
Raymond sum’s it up concisely:
Well-designed programs treat the user’s attention and concentration as a precious and limited resource, only to be claimed when necessary.
Eric Raymond’s Rule of Parsimony can be approached from several directions.
Write a big program only when it is clear by demonstration that nothing else will do.
Raymond discusses it in the context of volume of code, internal complexity, and maintainability. He also points out that people tend to be reluctant to throw away the result of a lot of work, even if it is a failure. In looking at the rule from the standpoint of design, I can’t help but hold up iPhone applications as a perfect example.
We are seeing a trend in recent years of smaller, focused applications that do one thing and do it very well. If Dreamweaver is the pocket knife that packs in as many features and functions as possible, but doesn’t do most of them particularly well, then applications like Espresso and CSSEdit are the craftsmen’s tools, each one designed for a specific purpose. iPhone applications are the same way. The best ones solve a single problem with a lot of attention paid to the details. Feature creep is anathema to the iPhone way of doing things.
When a tool is designed with a single purpose in mind, compromises don’t have to be made to account for other requirements. The singular purpose gets all of the time and attention. The result is a product that does what it needs to do in the most efficient, easy, and pleasing way possible.
Eric Raymond’s Rule of Composition has nothing to do with the layout of GUI screens. The rule states that programs should be be designed to be connected with other programs. It, in large part, discusses the use of simple text streams for communication and the importance of a well-defined API. The point that I want to focus on, however, is this:
To make programs composable, make them independent. A program on one end of a text stream should care as little as possible about the program on the other end. It should be made easy to replace one end with a completely different implementation without disturbing the other.
This is good advice for software design, but what wisdom can be drawn from it for the design of user interfaces? I’ve often had to design applications that are part of a larger system. They have to rely on other applications for certain functionality that are outside of my purview. One approach would be to design the application that I have control over so that it visually and behaviorally matches the one it links to. Of course, if it must interact with multiple applications, this approach isn’t possible. Even if it were, it would typically result in compromises to the user experience in my application that I’m not willing to make.
It’s better to make a clear distinction and provide the user with some indication that they will be reaching outside of the current application. Many websites visually distinguish internal and external links, for example. Many of the applications I work on provide links to PDF files. I make a point to indicate that clicking the button or link will open a PDF document. Another product I’ve worked on relies on a third-party application for OCR. The user leaves the first application, performs several steps in the OCR application, and then returns to the first to continue their task. It’s a difficult transition to make, and the UI has to handle many error conditions and communicate status effectively. However, it has been designed such that a different OCR application could be swapped in without much impact to the UI.
In many ways, this rule is in opposition to good UI design tenets, as we try to achieve a seamless experience. Sometimes, the seams are going to show. Take this into account in your design such that the experience is at least understandable and doesn’t take the user by surprise.