The Thing about YAGNI
The YAGNI principle (you ain’t gonna need it), as a design principle, in practice, is a very powerful utility for all software engineers to adopt and master.
However, it can cause issues when working in software teams.
It is clear that if you are effectively applying YAGNI in practice, you also deeply understand that context is everything, and that is the secret to achieving de-coupled software systems — that are easy to change, and remain that way over time.
So what’s the problem?
Well, one major problem of it is that, while YAGNI is a good individual discipline to apply, its not so obvious to others when and where it has been applied in a codebase by someone else. That lack of observability may stimulate misunderstandings from those that work in that codebase.
Let me explain.
It is all too common that inexperienced software engineers have this very strong notion that there is “one right way” to solve every problem in every context in software. They look at every piece of software against some purists exemplar in their heads. Rather then trying to understand that it-is-what-it-is because it was designed in that specific way for a bunch of real reasons at the time it was designed that way. (you could argue that some of these reasons were in fact not good reasons, and you may be right about that, but nonetheless, they were there at the time, and they had the effect they had). Instead of empathizing with that reality, its far easier just to say that those people at that time were just idiots. Hindsight is 20–20 of course.
The pursuit of that purest mindset is understandable, but it is a profound problem for them (and all those they work with presently), and they need to grow out of it. Which they will (we hope) if they were to stick with their profession long enough, and don’t fall into all those other all too common traps (like: remaining an expert beginner — I digress)
The real problem here with YAGNI is when a codebase that was designed using the YAGNI principles is encountered by someone inexperienced still stuck in the “one right way” mentality.
Why?
Because they are going to assume that when the codebase/library/framework whatever code they encounter does not suit or support their own particular use-case so easily for them, they will complain that — it just sucks!
Why does this codebase not deal with my use-case the way I want it? — waah!
In some cases, their reaction is going to be disgust, disgust at those people who went before them. A particularly pernicious reaction because it is likely to lead them to once again get out their ubiquitous “workaround” tool and workaround the limitation (and the intent of) the existing codebase they are working in, to get their job done faster.
Likely, by the way, creating future technical debt for the next person to clean up after them. This is after-all how big balls of mud cascade downhill— more shit just slapped on the side, and not bothering to integrate it into what is already there (to improve the whole system).
What they don’t understand is that, the codebase/library/framework was designed the-way-it-was specifically, because YAGNI does not try to predict all the future use-cases that could be possible, and shows no care for them.
That’s is what YAGNI tastes like, after its been applied!
Working in Teams
The super beneficial outcome of YAGNI can be a particularly serious problem if you are in the role of setting up codebases and code-frameworks to help others go faster, and those people take no responsibility in adapting them to suit the new version of the software they are creating now. Fancy building a framework?
What to say to those people that work within these creations?
The Disempowered
Well for starters. If they [rightly] feel they can’t (i.e. not authorized to or empowered to) change those codebases/code-frameworks, to accommodate their new use-case now, then they won’t even bother to.
Working around the limitation is the only one tool they have for getting their shit done.
For this, you need to make it very clear that adapting the codebase is part of what they should be doing as part of creating their solution. Making their work fit it. And that adding a new use-case actually changes the system, and that changes its overall design as well. They need to understand this and take ownership of it.
For that they need to feel empowered to do that themselves, not apply their “workaround” tool so readily.
I personally love when this happens, because when it does, they tend to understand that now, they are actually responsible for a change in the system that others are now going to encounter in the future, and then its not so easy to take the next position below.
The Irresponsible
Secondly, it is super easy to always expect that others are there to solve your problems for you. In this mindset, any problems that you may encounter you simply escalate to some one else to resolve. Now its their problem, and you are free of it. Your part is just to raise the issue, and it will get resolved for you by someone else.
Along with that usually comes a skeptical and cynical attitude about the work of others not being up to their ideal. Because they never have to make a real decision that could be wrong or questioned by others. Hence can continue to live in their ideal and bullet proof world, and that’s comfortable for them.
It is far easier to not have to take responsibility for a decision being made, and far easier just to whine about all the decisions that were made by others, and how you affected by them — waah! good for them, but not so good for those coming after them when it comes to writing software in teams.
What they need to understand, is what those others understood when then created the codebase/library/frameworks, whatever, with YAGNI. To apply YAGNI is to make a deliberate set of optimizations that deliberately minimize the complexity of the system, and in doing so, minimize what the system can accommodate in the future. In doing this, they made the code/framework/whatever more limited to work with, as is. Which is in fact a far better design principle than making it capable of solving all problems in the most optimal way in all cases. No such thing exists. Get over it — this is engineering we are talking about.
So next time, you have to work in a codebase that has applied the YAGNI principle, and you feel some friction from solving your specific problem in that codebase. Then I suggest that you:
- stop, and think!
- look around you, and ask yourself: “whether this friction is because my use case or solution hasn't been accounted for in the system yet?”. If it has, then go use that facility. But if not, then:
- Recognize that: there was a probably a very good reason for it —probably YAGNI, and then, (the critical thinking step)
- Ask yourself: “what could I do now to make this system better— using YAGNI — for the benefit of others coming after me?”.
You, and your work, will be much better to work with in the future.