Before my current incarnation as a UX Architect I was a Flash developer. I spent five years coding all kind of games, sites, and apps, and gradually progressed from simple bits of script to full-on applications and fully abstracted object-oriented code.
My day job now is focused on less technical work like research and wireframes, but I think during those years of coding I learnt some interesting concepts that I’ve carried through to this new role.
I recently wireframed a few simple online art activities for children which involve adding shapes to a canvas, animating a simple figure, making a postcard and so on. None of the activities are very complicated, but as we discussed time estimates and functionality my old developer habits started kicking in.
I found I’ve been thinking about how I’d go about building these apps, which led on to thinking about how that affects the how I wireframe things. As I did so, I found some interesting parallels and insights – so I thought I’d share them here.
These Art activities are small and there’s not much budget, so it’s important to find a balance between functionality and practicality; while we’d love to be able to create a rich, fully-featured Photoshop for Kids that’s not really feasible.
As part of this balancing act we need to prioritise features and functionality, assessing which ones are time-consuming to build and which are the most useful for the user. Some features, like an “undo” function, are useful but potentially quite tricky to make.
To unpick the undo function a little: when you click undo, you expect the canvas to revert to the state it was in before your last action. Exactly what that means depends on the activity: when you’re animating a figure, you want your figure to move back to its last position; if you’re drawing or painting you want the last mark you made to be removed.
So on the face of it, the undo functions across these activities work in very different ways – it’s natural to think of the function of the undo button in one app as “remove the last mark made on the canvas” and in another as “move the last moved limb back to its previous position”.
To the user, these are very different things. But to a developer using an abstracted, object-oriented language, there’s might be no difference between a button that undoes one thing and one that undoes something completely different.
In development terms, abstraction is about separating what the user sees from what’s actually going on in the application. It can be a tricky concept to grasp if you don’t have development experience, so here’s an example:
The user draws a line on the canvas, and then another. They realise the second line was a mistake, so click the undo button, which removes the second line from the canvas.
A good programme will give the user the feeling that when they draw on the canvas it’s their brush that is making the mark, and when they click undo it’s the button that’s removing that mark. But really, in the code, what’s happening is more complicated than that:
When the user clicks on the canvas, the canvas recognises the interaction and dispatches an event to say “I’ve been clicked here”. An abstracted (and invisible to the user) object called CanvasManager listens for that event.
When it hears the “I’ve been clicked here” event, CanvasManager adds the details of the interaction contained in that event to a list containing all interactions that have taken place. Once the new interaction has been recorded, CanvasManager clears everything on the canvas and redraws every interaction in the list.
When the user clicks the undo button, the button dispatches an event that gets heard by CanvasManager, which removes the last-added item from its list of interactions before clearing and redrawing the entire canvas.
If that sounded like complete gibberish then don’t worry – it’s the concept of abstraction rather than the practical implementation that I want to talk about here.
In this scenario, the undo button doesn’t simply remove a mark from the canvas, it’s part of an abstracted system that tracks interactions and draws or redraws the canvas as it goes. This undo button could be picked up from one activity and dropped straight into another, rather than being built from scratch for each different activity.
Now, for the user, that’s irrelevant – all they care about is whether the undo button undoes stuff. For developers, abstracting systems is a common way of separating form and function to create flexible, extensible code. But abstraction isn’t really something that gets discussed in UX – at least not explicitly, which I think is a shame.
For someone who spends a lot of time planning and wireframing, abstraction can be useful in a number of ways. Understanding how interfaces are built in abstraction is an advantage because you can understand the development implications of what you’re sketching and wireframing. Knowing which components and pages have the potential to be usefully abstracted can help you create wireframes that make good foundations for development, with the right balance of creativity and feasibility.
But perhaps more importantly, an understanding of how abstraction applies to wireframing also helps you keep an open mind about implementation.
Different people use wireframes in different ways. Some clients don’t mind rougher, low fidelity wires while others want them to be essentially a grayscale version of the finished site. I prefer to wireframe in loose, sketchy, black and white, trying to capture the essence of the subject before collaborating with designers and developers to solidify the details.
Abstraction can help you to do that effectively. It’s much easier to discuss how to implement a particular thing when there’s not already a decision made there on the page; abstracting the what and the why from the how lets you do that much more easily.
This kind of agnostic approach isn’t for everyone. Saying “I want a thing that achieves X” but not automatically considering how to implement it isn’t the most natural thing in the world, and some clients and workmates prefer a more concrete plan to work from. But if you can find developers and designers who can approach abstracted, functionally vague wireframes with an open mind and a good attitude then it works really well.
You don’t need to know about programming to start, if you want to try it. When you’re wireframing, just think about the user’s point of view – consider what they want to achieve and not how they should be achieving it. Rather than sketching the first (or second, or third) solution that comes to mind, keep things vague and discuss the problem with other people, whether that’s designers or developers internally or willing clients.
Have you tried it? Do you do it already? Do you do things a different way? Let me know!