KISS revisited

By Vladimir Khorikov

Today, I’m going to discuss the KISS principle. I consider it the second most valuable software development principle.

KISS: the principle

The acronym KISS stands for “Keep it simple, stupid” (or “Keep it short and simple”, according to other sources). It means that you should keep your system as simple as possible, because the simpler your application is, the easier it is to maintain.

This principle correlates with Yagni, but they are not the same thing. While Yagni states you need to cut off the code you don’t need right now, KISS is about making the remaining code simple. Here’s how it can be visualized:

YAGNI and KISS working together

YAGNI and KISS working together

Simplicity allows us to read and understand the source code more easily, and the ability to reason about the source code is vital for further development.

Here are three characteristics that can be attributed to any software system: Correctness, Performance, Readability. How would you arrange them by their importance?

It’s quite a tricky question, because the answer depends on several things, such as whether or not you will ever need to touch this system. But I believe for every typical enterprise application with a long development and support period the answer would be pretty much the same. So, what is it?

I guess one can think the order of importance is the following: Correctness > Readability > Performance. That is, the correctness is more important than readability which is itself more important than performance.

Now, think about it. Is it better to have an unreadable application that does things correctly than an application with bugs whose source code is simple and straightforward? In the short term, yes, it’s better to have a flawless system. But what if you need to add or change something in it? If you can’t understand the code, how can you implement the change?

It turns out that if you are ever going to enhance or evolve your system (which is true for most of enterprise systems), you are better off having one that is readable than the one that is bugless. The situation with the latter is unstable; most likely, you will introduce new bugs with the very first changes as you can’t fully understand it. On the other hand, with a readable and simple source code, you can find and fix bugs pretty quickly. That is, the order rather looks like this: Readability > Correctness > Performance.

There are two ways of constructing a software design: one way is to make it so simple that there are obviously no deficiencies, and the other way is to make it so complicated that there are no obvious deficiencies. – C. A. R. Hoare.

Simplicity vs Easiness

Simplicity shouldn’t be confused with easiness. These two concepts are completely different.

An easy solution is one that doesn’t take you much effort to implement. At the same time, a simple solution is usually far more difficult to achieve. It’s easy to create a complicated system that is hard to understand; it takes a lot of time to boil such system down to several core aspects and remove unnecessary complexity. Here’s a nice talk on that topic: Simple made easy.

This notion strongly correlates with the concept of technical debt. It’s easier to introduce technical debt than it is to remove it. A complicated system often contains a lot of technical debt, so you have to get rid of it in order to make the system simpler.

Accidental vs essential complexity

Not all systems can be made easy to understand. If you develop a CAD system, you can’t make it as simple as a To-Do List software, regardless of your attempts. You just have to understand 2D- and 3D-graphics and underlying math in order to build such application.

That brings us to two different types of complexity: accidental and essential. Essential complexity relates to the problem domain itself – the problem we need to solve in order to create the application. Nothing can decrease the essential complexity of a software system.

Accidental complexity, on the other hand, refers to the issues developers have to address on their way to solve the essential problems. Such things as cache management, optimization practices and other stuff that is not directly related to the application’s domain model is considered accidental complexity.

Most of the software engineering practices are aimed to reduce the accidental complexity, so is the KISS principle. The KISS principle has two main implications:

  • If you need to choose between two solutions, choose the simplest one.
  • Constantly work on simplifying your code base.

The first statement seems obvious, but too often I saw developers choosing a more complicated solution without any good reason. I guess, such decisions were dictated by a feeling that the simpler solution just isn’t solid enough for the problem they were working on.

In reality, the contrary is the case. The simpler your solution is, the better you are as a software developer. Most software developers can write code that works. Creating code that works and is as simple as possible – that is the true challenge.

Perfection is achieved, not when there is nothing more to add, but when there is nothing left to take away. – Antoine de Saint-Exupery.

Conclusions

A human’s mind can only handle 5-9 objects in memory. Throwing unnecessary complexity to code reduces your ability to reason about it and thus reduces your productivity. Even more, such reduction is not linear, but rather exponential. Increasing the unnecessary complexity of the code for just a little bit makes you times less productive when you work with it. Simplicity is the thing that is always worth investing in.

Other articles in the series





  • gabrielschenker

    Nicely said! With software development it is like with math, usually the first proof of a theorem is super complex but then eventually people figure out much more elegant and simple proofs. Kiss is an art.

    • http://enterprisecraftsmanship.com/ Vladimir Khorikov

      Thank you! Very nice analogy between math and software development, I totally agree.

  • David Raab

    What i think is important when someone discuss KISS is to explain the principle: “Make things as simple as possible, but not simpler” Because i have seen a lot of people that argue with KISS and provided things that are too simple.

    One case i always had was about database-design. When i design a database i alway try to normalize a database. And i always had someone that said. “Ah just put everything into a single table”. And his is argument was: “The design is just simpler with a single table. Think of KISS!”

    And it just drove me nuts to always hear it. This is just one example where the solution is oversimplified. Yes a single-table is simpler in designing it, instead of a normalized database with tables and foreign-keys, but it is not simpler using it. It will get so hard to query data, or even change data if you have redundant data all over the place. Queries are complex to even get the most simple data.

    So it is always important that KISS also has its limit, and to see the big picture. And that is what also a lot of people that argue with KISS didn’t do. I also had some other cases where someone wanted to write a big website, with concurrent users, a lot of data, and then asking about how to save data at best in a file. While most people said “Uh, use a database!” his answer was. “But a database is so complex, i just make it KISS and just save everything in files, and just open/close them to read/write”

    But he didn’t saw that his whole solution was a lot more complex than just using a database. If he would continued his approach he would even start to implement his own database. Because he faced the exact same problems that a database already solved. Quering and saving data in files in a fast way. And that was what he needed.

    But he didn’t saw that. And for him just opening and closing and reading/writing files was just more simpler as to set up a whole database and using a query language and designing your data in a database schema. Sure if someone just compares it on such a limit view a database is sure more complex. But it is the right and simplest solution if you have a problem that needs this complexity.

    So the important thing on KISS is, that it also has its limit, and someone always have to see the bigger picture on what he wants to do. For some things you want to do it is not simpler to just work with simple files.

    And i see a lot of people that use KISS in a wrong way. Like using YAGNI to an extreme it doesn’t make sense anymore (i wrote about it in your YAGNI article) .

    So while a think KISS is also one very important principle. I also don’t like it because it doesn’t show its limits.

    Instead of KISS i think we should rather prefer: “Make things as simple as possible, but not simpler”

    Because it makes us think about our solution if it is really the simplest solution for a problem that we have. With KISS itself people always start to forget the problem and just focus on the solution. But picking the simplest solution can be in the end harder for some problems. So it is always a “Problem -> Solution” we should have and not forget the problem.

    With just KISS a lot of people just focus on the Solution alone and start choosing solutions that in the end are more complex for some kinds of problems.

    • http://enterprisecraftsmanship.com/ Vladimir Khorikov

      Good points, and I agree, especially when you say that we need to always keep in mind the big picture.

      At the same time, I think you confuse a simple solution with an easy one. The use of files as a data storage doesn’t solve the problem of building a high-loaded application. If you try to create a reliable application using plain files, you end up building your own DBMS, which is way more complex solution than one that uses an existing database management system. This is a typical example of an easy solution, not a simple one.

      A non-normalized data structure is also an easy solution as it leads to increase of technical debt and brings to the table all the problems associated with it (redundant data, the difficulty of maintenance, etc.).

      A simple solution is not the one that takes little effort. In fact, it almost always takes much more labor that an easy one.

      >”Make things as simple as possible, but not simpler”
      It’s a nice catchy phrase, but I find it not very helpful in such situations. It’s hard to draw a line between a “simple” implementation and a “simple, but not simpler” one. I know, it’s often hard to distinguish a simple implementation and an easy one. Here is a simple checklist I use to do that, I hope you will find it useful:
      – The solution should fully address the problem (i.e. meet all the requirements).
      – It shouldn’t bring any overhead (i.e. accidental complexity, technical debt).

      The examples you provided don’t meet this checklist, so they simply don’t comply with the KISS principle. They are easy, but not simple.

      • David Raab

        The examples you provided don’t meet this checklist, so they don’t comply with the KISS principle. They are easy, but not simple.

        Yes they don’t meet the requirement. But that was the only thing i wanted to point out. That a lot of people uses such “easy” solution and argue that they are “simple” (KISS).

        • http://enterprisecraftsmanship.com/ Vladimir Khorikov

          Yep, I totally agree. There’s a lot of confusion here, people often use KISS (and YAGNI) as an excuse for choosing an easy way.

          • David Raab

            I found a video that discussed easy vs. simple and why we want simple things instead of easy things. And i had to think about this discussion.

            http://www.infoq.com/presentations/Simple-Made-Easy

            But on top of it i feel that what he describes matches what i said. In order to get simple things we have to do a proper generalization and abstraction. And those often cost more time in the beginning, but helps us later on.

            The talk is from Rich Hickey creator of the Clojure language.

          • http://enterprisecraftsmanship.com/ Vladimir Khorikov

            I actually have a link to this video in the article itself 🙂 Here it is: http://www.infoq.com/presentations/Simple-Made-Easy-QCon-London-2012
            It’s a renewed version of that talk which he did a year after the original version.

            In order to get simple things we have to do a proper generalization and abstraction. And those often cost more time in the beginning, but helps us later on.

            You are right. That’s why it is vital not to confuse easy solutions with simple ones.