June 7, 2023
We have three acronyms in programming that we cite all the time: KISS (“Keep It Simple, Stupid”), YAGNI (“You Ain’t Gonna Need It”), and DRY (“Don’t Repeat Yourself”).
These acronyms are advice for programmers. The first tells us to avoid unnecessary complications: write the most straightforward code to solve your problem. The second one advises against doing things we don’t need now because we think we’ll use them later: that happens extremely rarely. The third one recommends avoiding writing the same thing twice.
The echo that follows the DRY principle.
KISS and YAGNI are two pieces of good advice: they are easy to explain, understand, and apply. Are you going to do something complicated when you could make it simple? KISS: choose the simple option. Are you planning to write a framework that will let you export data to XML, JSON, Protocol Buffers, Thrift, and any other serialization format, existing now or in the future? YAGNI: follow your requirements, and if you need to export data to Cap’n Proto in the future, you can implement it then.
KISS and YAGNI are mutually reinforcing: if you don’t add things you don’t need now, your code is simpler, and vice versa. Both acronyms are like the two sides of a single coin or like electromagnetic fields: you can’t have one without the other.
You can’t say the same about DRY, though. If you follow DRY blindly, you’ll go against KISS and YAGNI.
For example, imagine you have three functions that happen to be almost identical. Since you want to follow DRY, you combine them into a single function. The problem is that this single function will have to do everything the original three functions did, making it quite complex. If you wanted to add the equivalent of a fourth function, this would complicate that single function even further, which is at odds with KISS. If you had kept them as three separate functions, you could have added a fourth one.
For another example, think of a web application that reads records from a database and shows them to the user in the browser. For this to work, there must be a record definition in the database, another in the server-side application, and another in the client-side application. Many think it is an intolerable number of repetitions, so, in pursuit of DRY, they write and use frameworks that let them define the records in a single place. The drawback with those frameworks is that they need to account for all use cases from the beginning, even if they never end up being used, which goes against YAGNI.
When I was a novice programmer, I wasn’t afraid of typing and copying and pasting and duplicating whatever needed duplicating: I still have the source code of a program I started in 1996 that was divided into several sections, and each section was written by sheer force of copy and paste and search and replace. As I learned and started taking DRY more seriously, my source code became more sophisticated: I wrote a lot of code I can’t make much sense of nowadays. Moreover, having to write the same thing several times made me feel so lazy and angry that I often wasted so much time looking for the perfect framework that I had no time left for programming.
Now I have a different attitude: some duplication does not hurt anyone. For example, when I want to generalize several similar code fragments, I wait until I have at least three instances (it’s impossible to generalize anything with only one or two examples.) And, when it comes to multilayer architectures, I see no problem with having a separate definition for equivalent objects in each layer. It’s a healthier and more productive attitude: I write more and better code and am happier.
Therefore, if you ask for my acronyms, here they are: KISS and YAGNI.
As for DRY, throw it in a lake.
|Previous: “Temporal paradox”
|Table of contents
|Next: “Project time”
|A Folla ten unha versión deste artigo en galego: “Do Repeat Yourself”.