We all try to be the best in what we do, to give the maximum of ourselves, and to achieve the highest results. Often in our desire to achieve the most, we try to look at problems from different angles and come up with the perfect solutions. We prepare very well and get to work. In theory, this sounds great. However, in our strive to develop the best solution, unfortunately sometimes we put pitfalls in our path. These pitfalls have a comprehensive expression. In this article, we will talk about two specific ones. From my personal experience, they are quite common. As a result, the famous rules, whose abbreviations are KISS & YAGNI were born.
Since both principles have existed since the dawn of time, most people are aware of their existence, but not of their importance. Therefore, I will mention each of them, what they represent, and the reasons why people neglect them.
KISS – Keep it simple stupid
This principle fights against the unnecessary complication of the software. Failure to comply with it occurs when instead of finding a simple and workable solution, we come up with a much more complicated version of what is required of us.
Let’s look at the main problems we may encounter when creating unnecessarily complex software:
- More difficult to develop – it takes more energy and effort of the programmer to invent and implement it. Energy and effort that can be distributed and invested more efficiently in other tasks.
- More time for development – needless to say, that time is one of our most valuable resources.
- A more complex technical solution implies more potential problems later on – this could also be costly. At best, the functionality won’t be approved by QA and we will have to fix bugs. However, there is a much more unpleasant scenario in which our functionality is already used by real users and they are the ones who discover the problem. Then the headaches increase many times over.
- The more complex technical solution is also a sure prerequisite for more difficult maintenance – as we know, programming is not strictly following rules and regulations, there are no textbooks for solving specific problems and as a result, their solution is mostly creativity. When it comes to creativity, the human brain has vast possibilities and understandings that are individual to each. Having that in mind, when creating new functionality, we must be aware that everyone who passes by us will have his own reading, and the more complex and abstract what we have done, the more likely this person will be confused and not understanding what we did.
- More complicated to change – in the dynamic world we live in, the rules of the jungle apply in full force to business as well – “It is not the strongest or the most intelligent who survives, but the one who best adapts to change.” Given this idea, it is extremely important to be able to react as quickly and efficiently as possible in case of change, and this cannot happen if our functionality is super sophisticated and two months after we created it, we can no longer understand it.
- Junior programmers suffer terribly – this is something that is relevant when creating software by more experienced programmers and affects the inexperienced. In my opinion, an extremely neglected point and something that few experienced people take into account. Initially from my observations, few people care about the inexperienced and do not try to make their lives easier, but in reality they are the heirs of what the elders have created and they are the ones who will continue their development.
YAGNI – You ain’t gonna need it
This principle is about not developing something that no one needs or something that might one day be used by someone. Let’s look at some examples:
- Functionality that is not required but we believe one day will be used – often when developing a solution, the programmer decides to be extremely resourceful and try to look a few steps ahead of the business people. He takes on the role of an oracle and decides to develop an additional or extended version of the functionality that is required of him at his own discretion and in an expression of goodwill. This would be great if it did not lead to the corresponding negative consequences:
- more time spent for him and everyone involved in the chain afterwards.
- Potential defects
- Higher probability that its bonus functionality will never see the light of day.
- A technical implementation that we don’t need – for example, we decide to make a helper function that converts dates from our time zone to UTC because we need it. Along with it, however, we think that one day, at some point, we might need functionality that converts one date format to another format. So we have started to implement the first functionality, why don’t we just implement the other one real quick. No, we don’t need that, and whoever will need it, will write it when the time comes.
- It doesn’t make much sense, but it looks cool – we’ve learned some new design patterns or some latest fad in programming and we decide to apply it as much as we can to solve our problem. It works, but as a bonus we add unnecessary complexity and functionality to our solution. This point largely overlaps with the KISS principle.
As a summary of this principle, we can say that most often actions contrary to this principle lead to unpleasant consequences similar to the KISS principle, such as – more effort, respectively slower development time, more maintenance and a higher risk of defects.
When and why KISS & YAGNI are not taken into account
Having considered the possible issues that non-compliance with these two simple principles can lead to, let’s consider the main reasons for their non-compliance, relevant at different stages of the professional development of each programmer. I will look at the main characters and share all my observations from my years of experience in the field:
Junior software engineers
The motivated, thirsty for knowledge and to prove themselves novice programmers – these are undoubtedly the uncut diamonds and the future driving force of any company. Everyone wants to have such people in their team. They often give a positive charge with their strong desire to face challenges and climb headlong up the ladder of their professional development. I dare say that in the first years of my professional career I was this type of programmer. In my desire to succeed, I fell into the trap of inexperience and ego.
The lack of practical experience made me think that the more complex a solution I come up with, the better I will impress those more experienced than me, which, as I already understand, is a big mistake. On the other hand, I often tried to think one step ahead of people who are much more skilled than me. It took me several years of work to make a proper self-assessment, and a lot of observation and training of other people to reach these conclusions.
Experienced software engineers
- Quite a large number of them who have encountered in their practice problems of different nature and difficulty tend to apply the so-called “over-engineering” approach. Initially, every experienced programmer tries to look at the problem from all angles. They also try to cover all possible input and output scenarios, to anticipate all possible problems that might arise. As a result, a solution is often reached that is possible to be much more than what is really needed. In other words, the most complex solution to the problem is implemented from the very beginning. A more appropriate approach would be:
- take into account all the criteria for drawing up the functionality.
- build a step-by-step plan, outlining all possible scenarios that need to be covered in the future.
- Implement as a matter of priority when necessary, instead of all at once.
- Some of them fail to mature and come to the conclusion that the complex solution of a problem does not mean that it is better. For some, the reason is ignorance and lack of experience. For others, it is the ego, the desire for self-expression and self-proof. Unfortunately, this results in less experienced programmers who do not have the skills and knowledge to understand more complex solutions, because they lack the experience and critical eye to determine whether a solution is optimal or not.
- Other senior programmers, decide that they want to try new and more interesting solutions to the given problems. This is a result of the long years of work in which the solutions to the problems begin to become repeatable. This is a great idea at first, but it often crosses the line. Projects with simple business requirements use unimaginably many new modern technologies and techniques that will make the daily life of the programmer more interesting. However, that comes at the expense of longer deadlines and therefore more expensive product performance.
- And last but not least, some experienced programmers just forget where they came from. They forget how hard it took them to figure out what a colleague with ten years of experience had written in their first month at work. This is something that everyone should keep in mind when writing code. Everyone needs to know that there will be both experienced and inexperienced programmers to support him. From this point of view, he should try to develop solutions that are as understandable and simple as possible, so that he does not have to explain them to every newcomer. This does not mean compromising the quality of our code so that beginners can understand it. It’s all about writing it in a simple and understandable way.
I would say that following some basic simple rules would bring great benefits to our professional development. I will try to summarize some of the main ones I follow when solving a problem:
- If the solution is too complicated, try and find a simpler one by looking at the problem from another angle.
- If the solution remains so complicated, Always discuss it with a business representative and explain in detail with arguments why a solution to the problem would cost a lot of effort. Then discuss possible measures that could be:
- Simplification of the requirements so that the effort meets the expectations of the business for resources and deadlines, but at the same time the results bring the desired value.
- Break down the problem into smaller parts and solve it over time by prioritizing and respectively delivering semantically separated valuable functionalities.
- Share the problem with as many colleagues as possible and gather feedback and ideas from them. “Two heads are better than one”.
- Creating a POC (proof of concept). Whenever there are more unknowns, it is good to make a simple solution to test whether the ideas behind it are well thought out.
- For beginners – whenever something seems too complicated, ask more experienced teammates about the problem or do a detailed investigation on the Internet. Given that you are a beginner, you are generally given more trivial problems, which often have a trivial solution. Do not try to “rediscover” the wheel.
These programming principles are quite tricky to apply. Each of us should try to write an easy-to-understand, simple, and easy-to-maintain code. At the same time, this must be done not at the expense of the quality of the final product and it must fully comply with our requirements. Good luck!
Written by Motion Software‘s Antoan Elenkov