There is often a lot of tension between User Interface (UI) Designers and Coders when it comes to deciding who "owns" which parts of a piece of software. It is relatively well known that there is some genuine overlap. Changes in UI can force change in deep architecture, and change in deep architecture can change the UI. Most folks realize that a good UI is not just something layered on top of an existing architecture.
Yet, even when you take that into consideration, and the people involved understand this, there are still sometimes significant conflicts between these groups. One group knows that the software must be like X, and another group knows just as certainly that the software must be like Y. Neither group makes much sense to the other. As a result, you get coders grumbling about the clueless UI people and UI people grumbling about the stubborn coders. (it isn't always like this, of course)
Sometimes I wonder why we need the two groups. Why not (say) get rid of the interface designers and just ask the coders to do all the work. On occasion, I've actually seen this done successfully. In general, of course, it doesn't work well. What is particularly funny for me is that I've spent many years as a coder and then as an interface designer. I think I do both jobs pretty well. Yet, when I put my coder hat on full-time, I tend to produce pretty poor user interfaces (which is embarassing). I've asked myself why that is. Which leads to this long blog entry.
After some reflection, I've come to realize that the design rules (if you will, their design heuristics) that coders and interface designers use are almost complete opposites. I believe that this underlies some of the reason it is sometimes so hard for one group to communicate effectively to the other. To make this concrete, a good progammer pays great homage to these rules:
* Make things modular
* Create general-purpose things
* Expose all potential functionality
In contrast, a good interface design involves these rules:
* Make things non-modular
* Make things as special-purpose as possible
* Hide non-crucial functionality
Let's look a these in more detail.
MODULARITY
Programming is immensely complicated work. Every line of code is essentially a tiny machine. So, a tiny program of 1000 lines is made up of 1000 machines. Can you imagine trying to build a physical device made up of a hundred thousand pieces? Does that make your stomach roll up into knots? Ever tried to reassemble a device with maybe 10 screws and found you somehow ended up with one extra screw? Now imagine a machine with five thousand screws. Yeah. Programming is very hard. One way of dealing with the difficulty is to put those lines of codes into very distinct clumps, and arrange these clumps so they do not interact with the insides of other clumps. This reduces the range of possible complications that can occur, and so reduces the chances of bugs occurring. This is called modularity. It keeps a programmer sane.
In contrast, a good user interface is not at all modular. If a term is changed in one dialog accessed from the file menu, then it must be changed throughout the application. More than that, changing that term may require icons elsewhere get changed, and sometimes can even involve adding or removing components in a dialog. For example, if the decision is made that the wad of data should be called a "zFile" rather than a "zRecord", then this might dictate that something resembling a file chooser should be used in some parts of the interface rather than a tabular list of records. Changes to the layout of components in one dialog might demand that other layout changes are made to all dialogs so that an overall consistency of experience is maintained. A good, quality interface expresses itself in the same way visually, terminologically, behaviorially, and even attitudinally throughout at least one application (and preferably throughout a whole suite of applications). Interface design is inherently and necessarily not modular (not for the sake of the designer's sanity, but for the sake of the end user's, since users expect things in their environment to be consistent).
Already, perhaps you can begin to see why interfaces created by coders are sometimes difficult to use. When confronted with a problem, a coder will tend to rely on the design rules they have spent years learning: make it modular. In fact, this is the design which makes the most sense to a person wearing that hat. It just isn't the design which makes sense to someone not steeped in that tradition of thought.
GENERAL PURPOSE THINGS
Related to the modularity issue is that of reusability. Coders are trained to write modules of code that can be reused. This is a significant way of saving time and effort. If you can create something once and reuse it repeatedly, that will obviously save you time compared with creating the same thing over and over again. The oportunities for creating general purpose modules is vast in programming. For example, operating systems can be thought of as vast collections of general purpose modules of code that are used by many coders. Within individual applications, there are often modules that are used heavily by different parts of the application. Because coding involves creating so much stuff, coders are always looking for ways to solve a problem in a general purpose way so that they do not need to solve it again later. When they're not creating general purpose things, they often are modifying existing things to make them more general purpose. Thus, a coder learns to do general purpose creation instinctively, and may add features to a module that won't be used at this moment because she knows those features will eventually be used by other parts of the program.
In contrast, good interface design often seeks to specialize. In theory, you could use a single piece of metal as a ruler, a nail file, a knife, a screwdriver, a pry-bar, and a putty-spreader, and many other things. But most of the time, we buy separate rulers, nail files, etc. Why? Because for practical reasons it is better to have a set of specialized devices than one universal one. We can put them each in different places, each can be fully optimized for its use, and so on. You might say that a tool is easier to use the more specialized it is, and the constraining factor here is how easily we can find and remember how to use the range of devices.
Again, notice that the coder and the interface designer approach their problem spaces with opposing attitudes. Also note that the coder's goal of modularity and generality reinforce each other, while the interface designer's goals of non-modularity and specialization mildly oppose each other. Interesting, eh?
EXPOSE ALL FUNCTIONALITY
Once you have created something that is modular and general purpose, you want to make sure that someone will be able to use it in any situation, including those that you haven't thought of. This means that you need to figure out every possible bit of functionality provided by your code (including those uses that might happen once every thousand cases), and then you must expose it so other modules can possibly use it. To do otherwise would compromise both its modularity and its general purpose use. Any coder has run into cases where some library they are using doesn't provide access to one bit of data or one "obvious" bit of functionality, and they must then devote large amounts of energy to providing some way of getting around that limitation. This is often painful and very frustrating (what would have taken the original developer maybe 5 minutes to do now takes half a day for the coder using that library). This pain teaches coder expose the full logical interface to your module.
Interface designers, on the other hand, know that people hate making choices. And when presented with (say) more than one thing, they slow down and have to make a choice. Thus, the best interface is the one that has the fewest choices. When there are genuinely a lot of things that someone can do, the designer learns to distribute the functionality in ways so the most frequently used functionality is most obvious. Other functionality may be buried (e.g. you have to open three dialog boxes to get at it), and there are other strategies to use as well. In some cases, some functionaity is just never presented, because it doesn't justify the pain it would cause users to decide whether to use it or not. A serious car enthusiast will tell you that you can increase the performance of your car by some percent if you go and adjust some things in the engine and then you will just need to monitor the adjustments more often. Many drivers, however, simply don't care about that. They would rather have a car which performs a little less well, and accept the fact that they can't adjust every detail. It is the same with users of software. Most people do not want to adjust their software. They don't even want to open a simple Preferences window if they can avoid it, much less be asked to choose between five different ways of rotating a graphic. Obviously, how much functionality someone needs depends on the user type and the task type. But it is usually the case that the end user does not want or need as much functionality exposed in their interfaces as it is possible provide. So, an interface designer deliberately hides or removes potential functionality in the name of making the software tolerable to use.
There are other differences between the disciplines, as well. A social psychologist will be able to point out different ways the members of these groups prove their value to each other, for example. I'm not going to go down route.
Instead, I'll just summarize by saying that practicing good UI design involves design rules that are completely in opposition to the design rules that a good coder must use. Each person can better understand the other's viewpoint in a given design discussion if they remember this, for it will help explain why the other person seems to be making "insane" design suggestions. Neither set of rules is inherently right or wrong, for each is necessary to the creation of quality software.
Posted by emily on October 17, 2005 at 01:59 AM PDT #