How to make your software obvious
Developers hate wasting time on documentation. We all wish there was less of it. This article shows you how to cut documentation down to the absolute minimum by following a few key development principles.
You know the frustration. You want to run a simple command, but it fails with some obscure AC35BA882 error code. Or worse, you just wanted to install a program and now you find yourself running through a thirteen-page Word document. You might even be in your fourth Stack Overflow post hoping to find that link to the official documentation that solved exactly your case the last time you had this issue.
All this is obviously a failure on the part of the developer. But how can we avoid leading our users on wild-goose chases?
In this blogpost we will outline a set of principles that you can apply to your own software and tooling.
Let’s get one thing right. Our mission is to provide value to our customers. If we don’t do that, we have failed.
So, when our software breaks, or is complex, it is our divine duty to make it as frictionless as possible for the user to get back on track and get value out of our products.
Whether this means helpful error messages, command completion or ample configuration examples, it is an important and often neglected task!
The roadblocks that are in the way of our users should be our first priority, even if we just enjoy tinkering with our code.
Let’s also accept the failures of our software. We are not perfect. The software is not perfect. It will never be perfect. Let’s own our failures and accept responsibility rather than going on the defensive.
It’s not (always) the customer’s fault our software broke.
I have a pet peeve. My soul dies a little bit every time a piece of software or a script crashes with a useless exception because some arbitrary folder it apparently expected is missing. It should not be an exceptional situation. The script knows exactly what the circumstances, problem and resolution are. So, what is your excuse for not letting the user know what is going on and how to resolve it? Or, better yet, ask if you should fix the situation for them.
This behavior leads to much frustration in users because we have a feeling that we did nothing wrong and yet the product crashed.
There is one thing I know with 100% certainty. If I have to do a manual task, sooner or later I will fuck it up!
If I have to create seven directories that need to be in very specific locations, ask if you can do it for me. I’m all for delegating.
Should the configuration be complex it must be accompanied by sufficient documentation and samples, but an interactive prompt that generates the configuration will be a big win.
And please make sure your software does something sane in the default configuration.
I love data and I can’t get enough of random statistics. But I’m also into developing debug information and user help. If information is not immediately helping the user to fix the issue on his own, then it is hindering the user.
Hopefully it is very rare that we at any point in our software do not know what went wrong. So use that same laser focus to clearly present the cause and resolution to the user. This empowers the user and provides for the most seamless experience.
Generally Git is great at this. The laser focus part is not always present, but after running
git status and actually reading the output, you seldom find yourself in doubt of what your actions should be.
Whether you are naming a function or describing a feature, make it obvious - not clever - what the purpose is.
When we are obvious about our purpose, of our intent, we give the user context. This helps the user to reason about the expected behavior of the item at investigation.
A configuration should not be named
TimeoutRetry. As a user, I do not know if I should use a boolean in order to have the software retry if something times out, or if I should give it a number. If I give it a number is it then a number of retries, or the timeout before a retry in what unit of time?
A configuration could be much more clearly named “RetryAfterTimeout”.
I’m a tools guy, so I live in the command line. We live by the idea that “the terminal is king”, and “nix is the only serious OS”. Sometimes I forget that this is not necessarily the world of our customers. Of the people that I am providing value to.
I might love doing my Git work in the terminal because that is the context that I am working in. But, if I’m not investigating the context the users are experiencing, I’m failing.
Hell, I’m a toolsmith. I’ll write that Jenkins plugin, build that Visual Studio integration, or create the alias so my users will feel awesome.
Aim to make your documentation obsolete. Not in the sense that it becomes outdated over time, but in the sense that the users only in the rarest of cases need to consult it. This means your software should be obvious, resilient to errors, and self-documenting.
Consulting the manual is the first step towards making a support request, so see it as an investment in minimizing your support budget needs.
Do you have a tendency to use the backlog as an eternal placeholder? If so, you probably have a lot of clutter that’s creating a lot of frustrations for your end-users. In this post we’ll show you how to clean up your Jira issues and reduce the backlog with some basic JQL queries.
Tips to improve project management in the Atlassian suite
How to test Kubernetes artifacts like Helm charts and YAML manifests in your CI pipelines with a low-overhead, on-demand Kubernetes cluster deployed with KIND - Kubernetes in Docker.
Low overhead, on-demand Kubernetes clusters deployed on CI Workers Nodes with KIND
Had enough of sluggish polling? With instant Artifactory event triggers you can give responsiveness in Jenkins a real boost. Here’s an easy way to set it up.
A super easy configuration guide
With the arrival of microservices code is becoming disposable. Does this mean that we no longer need maintainable code? Is it the end of refactoring?
Still relevant or increasingly redundant?
In software development tight coupling is one of our biggest enemies. On the function level it makes our application hard to change and fragile. Unfortunately, tight coupling is like the entropy of software development, so we have always have to be working to reduce it.
How to safely introduce modular architecture to legacy software
I am an Atlassian certified trainer and over the years I have been spending much time with clients and their Jiras. In this blogpost, I have collected some small tips and tricks that will make your Jira usage better.
Jira Software is a powerful tool deployed in so many organizations, yet in day to day usage people are missing out on improvements, big and small.
In this post, I’ll take a closer look at the version of Jenkins X using Tekton, to give you an idea of how the general development, build, test, deploy flow looks like with Jenkins X. How does it feel to ship your code to production using a product coming from the Jenkins community that has very little Jenkins in it?
A crash course in Jenkins X and how to test it out on a local Kubernetes cluster
In this blog I will show you how to create snapshots of Persistent volumes in Kubernetes clusters and restore them again by only talking to the api server. This can be useful for either backups or when scaling stateful applications that need “startup data”.
Sneak peak at CSI Volume snapshotting Alpha feature
When I read Fowler’s new ‘Refactoring’ book I felt sure the example from the first chapter would make a good Code Kata. However, he didn’t include the code for the test cases. I can fix that!
Writing tests for ‘Theatrical Players’
Nicole Forsgren and the Accelerate DORA team has just released the newest iteration of the State of DevOps report. The report investigates what practices make us better at delivering valuable software to our users as measured by business outcomes. Read on for our analysis of the report, and how it can be best put to use.
The latest drivers of software delivery performance
Hear about upcoming events in Scandinavia, latest tech blogs, and training in the field of Continuous Delivery and DevOps