Usage First, Implementation After: A Principle of Software Development
You know when you work on various projects, and you use various tricks and techniques, and they all seem independent from one another, until the big picture jumps at you and you realize it’s all connected?
I experienced this kind of aha moment, that emerged from several (apparently) independent topics I wrote about, a guest post from Miguel Raggi, and my work on three different recent projects. And I wanted to share this moment with you.
The common point between those sources is this: if throughout your development process, you think about Usage First, Implementation After, you will maximize your chances for:
- happy users,
- expressive code,
- faster development time.
The interesting thing is that “usage” and “implementation” have various meanings depending on the different stages in the development process. Let’s see 3 contexts where applying Usage First, Implementation After can bring the three above benefits.
The usage of the user
When thinking about usage, the first thing that comes to mind is how the user is using the application.
In this case, the principle of Usage First, Implementation After translates into the following guideline: decide about what’s best for the experience of the user, without thinking about how to implement the change in the application to achieve this user experience.
Granted, at the end of the day you will have to implement some features in the application to make this user experience tangible. But if you don’t think about the implementation during the reflexion about what would be great for the user, you are freeing your thinking from any limits. Pretend that anything is possible! This leaves room for more awesome ideas.
Only when you’ve decided what you want to do for the user, find a way to make it happen with the application. It’s only at this time that you should take into account the constraints of the existing system, the costs, etc. If necessary, you can always trade off 20% of user experience at this stage to make the development 80% cheaper.
The usage of the developer
Another usage that we think less about is the usage of the developer.
We don’t think about that first because the developer doesn’t use the app, and at first glance they don’t use the code either, they produce the code.
This view stands if the code is one atomic chunk that makes the application run, but it is not the case. The code is made of parts, many parts, and at many scales.
For example, the code of an application is often split into client and server, or front-end and back-end. And within any of those parts, there are modules, that can be composed of several sub-parts. And each piece of code in them is broken down into classes and functions, and so on.
All those are under the control of developers, and at each scale, there are usages: the client uses the services provided by the server, the front-end uses the API of the back-end, the modules uses one another, the internal code of the module uses the public interfaces of the classes, the functions use the prototypes of other functions.
All this is to illustrate that, from the perspective of any part of the code, there is a usage of another part of the code.
Write the call site first
The principle of Usage First, Implementation After applies very well in this context. In practice, it consists in writing the call site first.
Take the example of designing a function: imagine yourself in the middle of writing a piece of code, and you need an intermediary result in order to move on with the writing of your algorithm. You decide to write a function in charge of producing this intermediary result.
OneĀ way to design that sub-function is to think about what it will need and what it will produce, and then write the function. And once the function is written, to call it from the piece of code you were writing initially.
But a better way to go is the other way around: pretend the sub-function already exists, and call it. This leaves you all the liberty to write the call site that suits you best, including a name for the function that fits seamlessly in that context.
This is a very powerful technique to write expressive code.
For more details and a step by step example of this approach of writing code, have a look at this excellent article from Miguel Raggi: How to Write Simple Code to Accomplish Complex Tasks.
The usage of the data
Another situation I found the principle of User First, Implementation Later come in handy is when you have a system where you input data, and that produces data in another form. In this case the principle makes the development process faster.
Renting boats
Let’s take an example to illustrate. Imagine you own a boat rental on the beautiful Lac d’Annecy, where tourists are pressing in the summer season. You rent boats to people for them to take a tour on the Lac, and you want people to be able to book their boat in advance on your website.
The busy days are on the weekends and national holidays, although there is some activity during weekdays in the summer too. The inputs you feed your system are:
- the specific times your rental is open, for each type of day (weekend, weekday, summer season, etc.),
- the available boats and their hourly prices.
People can then book a specific boat for any amount of time, ranging from 30 minutes to a full day.
All that is the data coming in your system. In output, you need an up-to-date view of the available boats on the available slots for each day, so that potential customers can see what’s available in order to book their boat.
Designing the system
There are at least two ways to design this system:
- in order following the workflow,
- or Usage First, Implementation later.
The natural order that would come up to (my) mind is to follow the workflow. The starting point is the data provided by the boat rental owner: the opening times and boats descriptions. It sound only logical to start by thinking about how to take the data in input and how to store it, keeping in mind it will be queried later to display available boats and slots.
I have found that a much faster way is to start designing the end of the system first: the Usage of the data.
Doing that consists in designing the querying and processing of the data as if the data was already present in database in the most convenient format. The nice thing is that this defines what the most convenient format is.
From there, we go back to the beginning of the process, to design how to store the input data in this convenient format.
I used this approach on a project I worked on recently (even though it wasn’t about boats on the Lac d’Annecy) and I was impressed how it resulted in a better design, and a much faster development time.
How you design software
We’ve seen three aspects of software development where the Usage First, Implementation Later principle brought expressive code, fast development and happy users.
Do you also follow this principle or something resembling it? Please let me know how in a comment below, I’d love to read about your experience.
What others principles do you use when designing software?
You will also like
- It all comes down to respecting levels of abstraction
- How to Design Function Parameters That Make Interfaces Easier to Use
- Great Developers Don’t Just Write Great Code
- Runtime Polymorphism Without Objects or Virtual Functions
Share this post!