I see so much focus on how to create the perfect piece of software: easily maintained, extremely extensible, blazing fast and with beautiful idiomatic code. And all that is fine, but it's really just the last step when creating a program or feature.
The perfect software that noone uses
I think we've all been there: You're randomly browsing the web and then find a interesting project. And it has everything you could want: It's fast, it looks good and has an extensive amount of features, even some that you wouldn't even have thought of.
But you're not gonna use it. Why? Because you have no need to. Maybe you want bar charts and the software only makes pie charts.
The problem is that you'd rather use imperfect, buggy software that in the end solves one of your pain points than use a perfect software, that does something else. But as a developer it's often easy to forget that.
You've done this before
Make things that people want to use.
That seems obvious doesn't it? Yet it's surprisingly common to disregard this.
Filling a specific need is the basis of every entrepreneurial endeavor, but more often than that I've seen it disregarded in APIs. Too often I've seen what should be a simple API turned into a complex one by the addition of too many (unnecessary) features.
I know that I'm guilty of doing this myself before: Sometimes it's so easy to make something more powerful than it needs to be that it's hard to resist. But there is multiple problems with doing that:
- It needs more time to develop.
- The API becomes harder to understand.
- The code itself becomes harder to understand.
- The API will be harder to extend. Even when the added complexity is making it more extensible, if you need to change it in a way that was not foreseen, you'll now have to extend a more complex system and maybe even need to do extra work to support the additional features that might not even be in use.
Especially when your API is far away from your actual end user, it becomes easy to forget about the internal user. Yet, I find user-focus just as important when they are your colleagues than when they are your paying customer.
How can we stop over-engineering?
This might be different for each person, but the processes in most software development frameworks like scrum already try to have built-in safeguards against this. Sometimes even explicitly in the form of non-requirements.
Personally, I try to follow the following steps even in private projects:
- Specify exactly what I want to solve in this iteration. Usually this takes the form of a bullet list of 2-6 use cases.
- See if it makes sense to split it up.
- Write down how I would like to put my use cases into code.
- Write the necessary interface for these code samples.
- Think through how it would work and, if needed, add more inputs or outputs to the interfaces (e.g. you need user credentials after all; or you might have another error that you should report).
- Implement these interfaces. If I realize that I can't, I go back to step 3 and not any later step.
These steps help me to keep the focus on the actual requirements and not some potential requirements. I find it especially important to return to step 3 if you're stuck at step 6. Because that is the easiest way to make changes that negatively influence the API usage afterwards.
And since it can be frustrating to not get to implement the "cool but unnecessary" ideas, I like to write them down. That way I don't feel like I'm completely disregarding them, but that I can simply implement them at a later point if I decide that they are useful additions.
These steps should of course be fitted into your current framework – for instance in scrum you'd probably make a refinement somewhere between step 1 and 4 depending on the style of the product owner.
This topic might be one of those things where you can feel the seniority of developers. Most lists about the mistakes of junior developers include a form of "don't do too much". I guess, once you've written enough cool code that no one ever used, it becomes less fun?
Anyways, one of the more important skills of software engineers, I find, is to have a good top-down view. Don't just understand how to make things work the best, but also understand how to help your user the best.