January 10, 2009

...Learn TDD with Codemanship

Should UI Design Come Last?

One of the more worrying trends inspired by the dot.com boom was for software design to begin with a user interface design (basically, web page designs), and for our understanding of the logic of user interactions to be based on a bunch of static web page mock-ups, or - if we're really lucky - some screen flows and a few UI storyboards.

There are some major pitfalls to the UI-driven approach that I've witnessed on many projects:

1. The UI design is a solution coming before we've really understood the problem. And we all know where those tend to lead - software that often doesn't actually solve the real problem.

2. Working from UI mock-ups and static HTML pages is like giving animators a bunch of cartoon character sketches and then telling them to "make the story up" based just on that information. Behaviour is the vital missing ingredient: what will this character do in response to this stimulus? How does he move? How does he act? How does he interact with the other characters? It's the same question as: "what happens when I press this button?" All too often, the UI designer hasn't actually thought the behaviour through, and we're forced to do more requirements analysis and then somehow transplant the required behaviour onto the UI design.

3. People can get very attached to their designs. It's a cliche and a stereotype, but I have to admit - in my usual unqualified, subjective way - that I have found over the years that web designers seem to be especially protective of their "babies", and I've seen some huge battles, with much gnashing and wailing of teeth and tears before lunchtime, when lowly programmers dared to even suggest "tweaking" the UI design to accomodate the small, insignificant detail of utility. My own experience has been that, once created, UI designs have a tendency to stick. That's the point in a project where the wind changes, and you really need to try and get as good an understanding of the requirements before that moment as is humanly possible. In Agile juice bars, we call this Big Design Up-Front...

All in all, it seems to work much better if we take the time to understand the behaviour - expressed in terms of the domain - and construct a logical interaction design before we think about how that can be expressed as a physical user interface.

Let's imagine we're building an application using the Command pattern, where key user actions are executed by specific Command classes that manipulate the business objects in our system. These commands would represent the logical interaction model for our system. Ignoring the user interface at the beginning, we could focus on what these commands do, what parameters they require, and what rules they must obey.

We could explore this behaviour using test cases. These tests could be expressed in a Domain-Specific Language we construct that maps on to the Commands (e.g., a macro language).

This is where we start to make some real progress in our understanding. A user interface design is actually a visual DSL that incorporates symbols (icons, buttons, drop-down lists etc) and actions (mouse clicks, dragging and dropping etc), allowing users to express their intentions to the computer via the software we write.

So what I'm really talking about here is the need to understand the semantics of that visual language before we commit to a concrete, physical syntax.

Remember our test cases, expressed in a DSL that represents the logic of our commands: what our commands do is the semantics of this language, and the textual representations ofthis (e.g. as tests) is the abstract syntax of our user interface. On to that we could map a command line interface (like we did back in the bad old days ), or we could map Windows and widgets, or we could map HTML, or Flash, or Silverlight, and so on.

My - probably very laboured now - point is that our user interface is a visual language, and when we design languages we would be better off starting with the semantics, followed by the abstract syntax, ending with the concrete syntax last once we've thoroughly tested our understanding of the former.

In a test-driven process, this would probably mean that acceptance tests come before UI mock-ups. Indeed, I would probably recommend writing software from the controller layer down, passing your logical acceptance tests, and then designing and implementing the user interface with customer input.

Posted 9 years, 5 months ago on January 10, 2009