Skip to main content

Keep It Simple, Stupid (KISS) Principle

Introduction

"Code is like humor. When you have to explain it, it’s bad."
-- Cory House

Kiss Icon

The KISS principle originated in the U.S. Navy in 1960. The principle states that systems work best when they are kept simple.

In software engineering, the KISS principle is a design principle that suggests that using simpler solutions is better than complex ones. Such code is easier to maintain, debug, and understand. This applies to implementation details, architecture, and even the processes we use to develop software.

Acronym alternatives

Not everyone appreciates this acronym, as it can come across as a little rude. There are many polite alternatives to the KISS acronym, such as:

  • Keep It Short and Simple
  • Keep It Simple and Straightforward
  • Keep It Super Simple
  • Keep It Simple and Smart

I've chosen to use the original acronym here, but feel free to use any of the alternatives that you prefer.

KISS in Code

The most common place where the KISS principle is applied is in writing code. Simpler code is easier to understand, debug, and maintain. There is a strong temptation to be clever when writing code. We want to show off our skills and write code that is elegant and sophisticated. However, this often leads to code that is difficult to understand and maintain.

Simpler code is also less likely to contain bugs. There's just fewer places for bugs to hide. Finally, somewhat counterintuitively, simpler code is often faster, and much easier to optimize, than more complex code. The compiler may be able to do much of that optimization for you, but even if it can't, bottlenecks are easier to identify and fix in simpler code.

Prioritizing simplicity will produce code that is easier to work with, both for you and for others. Here are some ways to apply the KISS principle in code:

  • write simple, readable code
  • prioritize clarity over cleverness
  • avoid over-engineering
  • avoid deep nesting

Giving good code examples for the KISS principle is a bit tricky, as the principle is more about the absence of complexity than the presence of simplicity. Examples that are simple enough to understand are often too simple to demonstrate the principle.

Let's try a familiar problem that most people have encountered at some point. Consider the following implementation of the classic FizzBuzz problem:

fun fizzBuzz(n: Int) {
for (i in 1..n) {
if (i % 3 == 0) {
println("Fizz")
}
if (i % 5 == 0) {
println("Buzz")
}
if (i % 3 != 0 && i % 5 != 0) {
println(i.toString())
}
}
}

This implementation is the classic one that many developers come up with when they first encounter the FizzBuzz problem. It is reasonably simple and easy to understand. However, using the % 3 and % 5 conditions combined to create the combined string is a pointless piece of complexity. Adding a separate condition for % 15 would make the code simpler and more obviously correct. Here is a simpler implementation of the same problem that also exploits the when construct in Kotlin:

fun fizzBuzz(n: Int) {
(1..n).map { i ->
when {
i % 15 == 0 -> println("FizzBuzz")
i % 3 == 0 -> println("Fizz")
i % 5 == 0 -> println("Buzz")
else -> println(i.toString())
}
}
}

This implementation is simpler and more readable than the previous one. It obviously prints the correct output for every case.

KISS in Architecture

The KISS principle can also be applied to software design and architecture. When designing software, it is important to keep the architecture as simple as possible. This means using simple design patterns and avoiding over-engineering. The goal is to create a minimum viable architecture that meets the requirements of the system without adding unnecessary complexity.

Add complexity only when the system requirements demand it. This will make the system easier to understand, maintain, and extend. When adding complexity you need to ensure that it is justified and that it is adding value to the system.

When designing software architecture, it is important to consider the following:

  • use simple design patterns
  • avoid over-engineering
  • prioritize simplicity over complexity

The concept of minimum viable architecture is an important one for the KISS principle. It is especially relevant for startups and small companies that need to move quickly and iterate on their products. The goal is to create an architecture that is just good enough to meet the current requirements of the system. This allows the team to move quickly and make changes as needed. Almost no project at a startup should begin as a microservices architecture, for example. That level of complexity is rarely justified at the beginning of a project.

KISS in Processes

Your processes should both be simple and help you to keep your code simple. If your processes are too complex, they will slow you down and make it harder to write simple code. For example, if your code review process is too complex, it will slow down development and make it harder to write simple code. If your deployment process is too complex, it will slow down development and make it harder to write simple code.

The single most useful piece of advice for efficient software development is to work in the smallest blocks possible. Getting prompt feedback on your work is the key to improving your code and your processes. The smaller the block of work, the faster you can get feedback on it. This is why agile methodologies emphasize working in small iterations.

Automation is another key to keeping your processes simple. Automate as much as possible, from testing to deployment to monitoring. Automation reduces the chance of human error and speeds up development. It also makes your processes more repeatable and reliable.

This mindset also needs to apply to communication. Streamline communication as much as possible. Use tools like Slack, email, and project management software to keep everyone on the same page. Make sure that everyone knows what they need to do and when they need to do it. This will help to keep your processes simple and efficient.

KISS in Tools

When building internal tools or interfaces, it is important to keep them simple and easy to use. The goal is to create tools that are intuitive and require minimal training to use. This will make it easier for your team to adopt the tools and use them effectively.

If you are building platforms or security tools, it is even more important. You are trying to streamline the development for other teams. The only way you can succeed is if using the tools is easier than bypassing them. If your tools are too complex, teams will find ways to work around them, which can lead to security vulnerabilities and other problems.

When to Break the KISS Principle

The KISS principle is a good rule of thumb, but there are times when it is appropriate to break it. The key is to break the principle only when it is necessary and when the benefits outweigh the costs. The most common cases where this happens is when the non-functional requirements of the system demand it. For example, if the system needs to be highly performant, scalable, or secure, it will be necessary to add complexity to the system to meet these requirements.

Conclusion

While the KISS principle is a simple concept, it might be the most important principle in software engineering. It is the foundation of many other principles and practices. Prioritizing simplicity will make your code easier to understand, maintain, and extend. It will also make your processes more efficient and your tools more effective. The KISS principle is a powerful tool that can help you to build better software.

Look for ways to simplify your code, and if you succeed, do it again.

Image Credits

Dinosaur icons created by Freepik - Flaticon