I was recently in the CodingCoach slack when a fella by the name of Shayan asked a question. He said:
Guys I did some research around KISS, YAGNI and SOLID principles, there seem to be many good resources about SOLID, but I couldn’t find anything about the two other ones
He makes a good point, whilst I’m sure on a long enough timeline you’d find some articles on KISS (Keep It Simple Stupid) and YAGNI (You Ain’t Gonna Need It) I can imagine straight explanations of the two concepts being a little thin on the ground.
So, now watch as I courageously write an opinion piece on the internet about loosely defined topics that a lot of people have encountered, with little to no regard for the fact that the comments section will inevitably become awash with a heady mix of “I couldn’t agree more”s and “Well, actually….”s.
In all seriousness though, what follows is a completely biased, opinionated and personal experience based view on what KISS and YAGNI are and what they mean to me. My hope is that you can take these opinions and use them either as a basis to begin forming your own opinion, to augment your own opinions on them, or to once and for all confirm to yourself that I have no opinions of any value (get Tyrannosaurus-rekt Zac!).
If you have anything to add to what I’m about to say in this post please feel free to add a comment to help future readers get a fuller picture of these topics.
Before we spend time discussing what my definitions for these terms are I thought it might be worth spending a short amount of time hypothesising why I think that Shayan might have had so much trouble finding reading material on these two concepts.
My guess would be that the problem stems from the fact that these principles are rather soft concepts. There aren’t really hard and fast rules that you can apply to say definitively, “Yes, I conform to the principles of KISS and YAGNI”. Also the principles are very subjective both to the individual applying them and the situation that they are being applied.
At the end of the day, conforming to KISS and YAGNI is more of a state of mind or an attitude towards building software. Most often people gain this attitude or state of mind shortly after the first time they start feeling the pain of code that was written in a way that doesn’t observe these principles.
What I’m leading towards here is that I hope you understand that these principles are so loose that not only are my opinions on them open to interpretation but also the way in which you apply them will differ from case to case. Given that, what I would suggest is that as you read further what you really should be taking on board here is the core of the principle rather than any specific examples I give. The examples are there to demonstrate the point not give a prescriptive catch-all for every time you see something similar to the example out in the wild. So, without further ado let’s jump in:
KISS: DETROIT! CODE! CITYYYYYY!
Keep It Simple Stupid, or the KISS principle, kind of does what it says on the tin. KISS suggests that you should avoid trying to outsmart yourself when you code.
As developers we spend a lot of time collecting new tools and tricks for our metaphorical tool box. When we get a new tool the inclination is to try and find a use for it. Most often this results in developers writing solutions which use methodologies that don’t fit the problem.
You will see this happen particularly with developers who are first learning design patterns. Patterns are a very powerful tool and if used wisely and pragmatically can create powerful software that is easily extended and maintained. However too much of a good thing, ain’t a good thing! Sometimes in the search for an elegant, maintainable and extensible solution, developers can go over the top with patterns and build something that is an overcomplicated mess.
Don’t get me wrong, this mess comes from a good place. Developers want to put their best code forward. They want to write elegant solutions to problems. They want these solutions to be supremely equipped to deal with change and give them the velocity that they’ve always been promised if they just maintained vigilance when it comes to building their solutions.
The problem that a lot of developers fail to see is that when it comes to maintenance and extension of code using well known structures is only one way of allowing for this. Without a doubt the number one thing that will allow developers who are going to change or extend the code you’ve written is that the code is easily understood. This is super important in 6 months+ time when another developer or even your future self needs to remember how all this stuff hangs together.
We must remember that the measure of good code is not the number of patterns that we’ve foisted into the solution but rather how easy it is to read and understand. This ultimately is an indicator of how easily it can be modified.
Now that doesn’t necessarily mean that the simplest piece of code possible is automatically the best code you can write. There is definitely room for elegance and some problems are just complex and require complex solutions. What KISS is hinting at is that a solution should always be striving to remain simple enough that anyone on your team could easily understand it with no knowledge of how the code currently works.
When you think about it objectively this is a wise move. Every time you write something that isn’t obviously understandable you run the risk that the next developer who works on your code doesn’t understand your code’s intention. This could then result in that developer using your code incorrectly!
How simple is simple?
Of course observing KISS is a good thing but the problem with it can be that keeping something simple can be subjective to the person reading the code. Some people are able to hold extremely complex code in their head, juggle in one hand and stir a latte with another whilst reciting the alphabet backwards. Whilst other developers might be at the stage of their career where recursion represents a complex topic for them.
Earlier I was saying patterns can be how developers contravene the KISS principle. But patterns can also actually be how you are able to level out the knowledge differential I described above.
Patterns allow developers to solve well understood problems in a well understood way. This allows for developers with a greater amount of experience to freely use a level of complexity appropriate to the problem. At the same time if another developer has a hard time understanding the solution then they will have a wealth of information available to to them to help them understand the precise meaning and implementation of the solution.
So you can see the trick I’m suggesting isn’t to use no patterns at all, but instead to use a pragmatic number of patterns that are well suited to a problem for which you can create a solution that is both simple and elegant. This will allow you to achieve both goals of having your code be well equipped to handle change and also be easily understood by other developers.
This is just one way of applying KISS to a problem but there are many others that I’m sure you’ll find now that you have grasped the core concept.
Put the crystal ball away: YAGNI
You aren’t gonna need it, the immortal words of wisdom of Ron Jeffries as part of the Extreme Programming movement. The basis of this mantra is also simplicity but in a slightly different way to KISS.
Where KISS suggests that you implement the full solution to a problem in the simplest way possible YAGNI asks the question of whether everything in the full solution is really necessary.
When developers learn to make software that is extensible there is sometimes an inclination is to try and make things in such a way that any possible incarnation of the solution would be possible in the future. Things like “Oh, we want to multiply right now, but what if we want to divide? We should implement that too whilst we’re at it!”
YAGNI promotes both pragmatism and simplicity. It advises against building for use cases that aren’t explicitly necessary for the purpose of supplying the functionality you’re trying to provide right now.
YAGNI says that building for these unnecessary use cases complicates the program, by solving problems that are probably not even going to be a “thing” in the software that you’re writing. In the previous example; sure you might need a divide but what if you don’t?! Now you’ve just had to build things like account for divide by zero errors for a piece of functionality that you aren’t even going to use!
The way in which YAGNI promotes pragmatism is that YAGNI suggests that you should remain focused on solving the problem that you’re trying to solve immediately rather than making an attempt to solve all the world’s problems with the solution you’re writing right now.
As we’ve seen both YAGNI and KISS are loosely determined principles which at their heart are concerned with simplicity. The reason why we strive for simplicity is because as human beings we have differing tolerances for being able to hold complicated things in our heads. So by following these principles we’re trying to do ourselves a favour by making the code that we write and more importantly, read simple enough that we can grok it. In this way we empower ourselves to make smart decisions when it comes to maintaining and extending it.
YAGNI helps us to achieve simplicity by reminding us that we don’t have to solve for every use case in the first iteration. Even if we could we’d be wasting our time because really we only care about the use case we’re solving for now, not the 100 others that we MIGHT need in the future.
KISS helps us to achieve maintainability and extensibility in our code by reminding us that readable code beats clever code every day of the week.