This week I’ve been re-reading John Maeda’s book The Laws of Simplicity. It’s a handy size to read on the train and contains a number of useful mnemonics for adding a sense of elegance to your design. The section that I often quote to others relates to how to deal with delays, as they may be perceived by users and customers. The themes are important enough that I feel the need to restate my own version of them as they apply to software architecture.
Let’s say you are building a web shop. Potential customers can stick widgets in a basket and, when they are happy with their order, follow a fulfilment process. Part of processing the basket contents is to make sure that the selected widgets are in stock, and that the combination of widgets doesn’t invalidate any special offer rules. Because some actions in the process will necessarily entail communications with laggardly heritage systems, that can only process data sequentially, you will have to deal with the delay this will add to the processing time. In the worst case, bored customers might go elsewhere, but even if not, their experience in those critical minutes will create an impression of your company that needs to be a good one, so this is not an issue to be taken lightly.
From an architecture perspective there are four things you can do to keep the suits (and the customers) happy. Ideally, you want to apply all four to varying and appropriate degrees, but for individual reasons one or more may not be possible.
Address the delay
Clearly the first tack ought to be to reduce the delay head on. Think about making some calls asynchronous. I’m not in the camp of everything-should-be-async, but many operations can be made to work well in a disconnected fashion. In the case of a stock check, an async call can be used to facilitate a backorder process. If your particular brand of widget allows for this, then it can even be an improved customer experience. If I order a book from Amazon and it’s out of stock I’m usually cool with that, as long as they give me a rough idea of when I might get it so I can decide whether to wait or look elsewhere.
Embody the delay
If you can’t reduce the delay, reorder operations so that the longest bits happen early while later bits happen in parallel. For example, do that stock check as goods are added to the basket, so that there’s more time to play with before payment details need to be entered. User experience needs to be walked through in quite some detail here though to avoid bad experiences - don’t, for instance, stock check at the start of order processing and move to parallel payment details, only to tell your potential customer that the goods they want aren’t in stock after they’ve completed billing address, delivery address, and stubbed their toe looking for their credit card.
Hide the delay
If you really have to have Mr Customer sitting there while back office activity takes place then give them something to look at. An egg-timer is a start, but you can be more creative as long as the download time for the distraction isn’t going to be a delay in itself.
Explain the delay
A constant message in John Maeda’s book is that knowing stuff, or feeling stuff, as a user goes a long way to providing that warm fuzzy feeling you get when you interact with a great service. So don’t hesitate in being explicit in the on-screen dialogues as to what’s going on. Every time you know something in the code, let the user know, this goes for errors too. It helps engender a better relationship, and leads to more sales, if both ends of the customer-supplier transaction are in sync with each other.
Life is full of periods spent waiting for things (it’s 11:30am now, and by my reckoning I’ve already waited for nearly an hour for two trains and a coffee). The majority of people will be fine with a few seconds here and there while you service their needs, what nobody likes though is hanging around when it feels unnecessary or when they have no idea what’s going on.