Programming

User-Facing Features: Why Not?

A Story

An engineer coworker (years ago now) described how he was building a feature to allow appearance themes (sets of colors) and that he admitted he was not a graphic designer (trying to push this responsibility onto other members of the team). In discussing this he also implied that this feature should be exposed to the end-user (now he’s pushing this onto the end-user?) I did not deny that he may have been doing good work technically and that separating out the visuals into all-encapsulating theme “packages” would be a fine idea, but I disagreed with the idea that just because something is implemented that the user should be allowed to or forced to deal with the details.

The simple question that bothered me was that he asked: why not?

Later I realized how to answer that question.

It is not a matter of: if the user can do it then let them do it. Users do not want that power. (Just like they do not want the power to accidentally delete their data, etc.)

The question should really be flipped around and asked: should we really bother the user with this without a good reason?

More simply: the oblivious engineer asks why not bother? (the user) but the real question is: why bother? (the user).

A Moral

The point of great software is not what it allows a person to do but rather what it allows a person not to do. Not bothering the user with details that are the responsibility of the developers is a service to the user. The software should save them time, not give them extra work to do.

Why expose something that the software developers and designers can take care of on the user’s behalf? Why make extra work for them? The engineer must justify any and all features by asking these questions. If it is a matter of aesthetics only but there is no utility, or if there is negative utility (more work for the user to do that they shouldn’t be bothered with), then that should tell us something.

In contrast, allowing the user to change the colors of individual items of data for semantic reasons is obviously a good idea when it is a core part of the visualization aspect of the specific piece of software and allows users to make their intended meaning instantly identifiable, which saves them time and enhances the power of the software’s visualization.

But allowing the user to theme parts of the interface that really have no bearing on the core point of why people would use the application just creates extra features to maintain and extra cognitive load for the user. Especially when those parts of the interface use standard controls on other platforms and allowing the user to change it on one platform would create inconsistency.

Software Design, More Generally

So in writing this essay, I figured out what it was about his comment that bothered me so much. And the problem wasn’t specific to him necessarily but rather the attitude of a lot of programmers and their obliviousness to the importance of design from the human standpoint, not from the artsy-fartsy standpoint. Even worse is when they say, “I am not a designer nor do I claim to be one,” but they think that design only has to do with choosing colors and making things look pretty! Or their understanding of design is so lacking that the features they implement have to be rebuilt because of their lack of understanding of how to build and test user-facing features, their lack of understanding of what to build in the first place, or whether the feature should or should not be built in the first place!

You see this all the time with lots of “powerful” open source software: instead of doing the work up front to prevent the user from doing stupid things, the engineer punts and says, “Let the user deal with this: here are myriad sliders and controls and they can just make sure the combination of settings makes sense. (Coincidentally, each slider is trivial to implement!) I am doing the user a favor by directly exposing all of the internal knobs and levers for them to tinker with. If they get the software into a bizarre state that is on them.”

An example of this in a single domain: Readium and Calibre (two very useful and powerful OSS projects) vs. Apple’s iBooks epub reader app (now Apple Books, iOS and macOS). Apple’s app allows you to change the appearance of an ebook that you are reading, but notice that there are only four pre-made themes or foreground and background color combinations, and notice that no matter how you rotate your device or change the text size, you cannot get it into a bizarre state. As a bonus, single v. double column mode is entirely automatic. Contrast Readium and Calibre, where there are more controls but it is too easy to combine visual settings in a bizarre manner, for example text columns that are too thin or too wide, having to manually turn single v. double column mode on and off manually, red text on a blue background, etc. No thought for preventing undesirable states, and pushing the responsibility onto the user.

A good engineer who thinks in terms of “design is how it works” will move mountains (write lots of thoughtful, technically challenging, invisible code) to make the software more clever in order to save the user just a small fraction of extra work, and to avoid having to add a manual setting for the user to fiddle with. Just because the engineer knows that internally the machine works by taking a bunch of knobs as input and producing some output doesn't mean they will then directly expose all those knobs as the interface for the user. Some thoughtfulness is required.

Software design is a subtle art. Some engineers take for granted their relationship with the end-user of the software. Engineers excel at using diverse tools to create custom software to make a computer do whatever they want. Engineers often favor a toolkit approach, where maximum flexibility is paramount. Ease of use is less important because the engineer is an expert and understands in excruciating detail how the machine works and how her software works or does not work. Fragile workflows or complicated multi-step workflows are considered acceptable if new objectives can be achieved with less total work for the programmer/engineer. Make the machine do what I want. The end justifies the means.

Users on the other hand favor ease of use, abstraction and integration. Users are uninterested in the technical details of how something works and are task-focused. They care about how a task is done (the means), how to remember how to do it, how to discover how to do it, how to avoid extra work. They want their software to just work and they want the interface to reflect the exact state of the data at all times. They value integration, where a single piece of software can do everything they can imagine with their data without having to make the user manage interoperability between multiple applications. They are uninterested in what is possible to do by combining different tools in clever ways and just want an easy, reliable way to go from idea to implementation with minimal fuss. They don’t want to be responsible for understanding the underlying details to accomplish their work or even worse, safeguarding the integrity of their data. They don’t want problems to be their fault. They don’t want problems at all. Their powerful machine and powerful software should see to that.