Clean Code o el sentido común en la programaciónClean Code, or common sense in programming

He dudado mucho de cuál debía ser el tema de mi primera entrada técnica del blog pero una vez me vino a la cabeza no se me ocurre mejor opción.
Clean Code, de Robert C. Martin, también conocido como Uncle Bob, fue el primer libro que leí por gusto una vez acabada la carrera y empezado a trabajar con el objetivo de ser mejor programador. Siento no haberlo hecho antes, pero hacerlo en ese momento, después de tener algo de experiencia y haber sufrido codificando, me hizo entenderlo y valorarlo mucho más.
Recuerdo perfectamente las sensaciones mientras lo leía, porque me pareció que todas aquellas ideas eran de sentido común. Aunque como se suele decir, a veces, el sentido común es el menos común de los sentidos.
Después de mi primer desencantamiento con el desarrollo, me sirvió para recuperar la motivación y tomar impulso, para comprender que se podían hacer las cosas mejor, que todas aquellas inquietudes y sensaciones que estaba sintiendo en el trabajo tenían sentido y eran compartidas por muchos otros.
¿Qué es Clean Code?
Lo primero que debemos preguntarnos es: ¿qué es el código limpio? El concepto es bastante abstracto. Al inicio del libro se pregunta a importantes desarrolladores de la industria qué significa para ellos y, en sus respuestas, se pueden encontrar grandes ideas concentradas en unas pocas frases. Ideas que hacen referencia a principios, patrones y buenas prácticas de desarrollo. Mis favoritas para definir qué es el código limpio son:
- Se lee como un buen libro.
- Transmite que ha sido escrito por alguien a quien le importa su profesión.
- Es elegante y sencillo. Tiene el mínimo número de elementos necesarios para cumplir su función, sin adornos ni duplicidades.
- Es previsible. Cada elemento está en el lugar y hace el trabajo esperado.
- Puede ser traspasado para ser mantenido y evolucionado por otros desarrolladores que no sean su autor.
- Tiene tests automáticos y todos pasan.
Principios del Clean Code
Han pasado muchos años desde que leí este libro. Siempre pienso en releerlo, pero mi pila de libros pendientes no me da mucha tregua. Quizás después de escribir esta entrada sea un buen momento.
Aunque haya pasado tanto tiempo hay ideas que se me quedaron grabadas, por lo que me transmitieron al leerlas y por como he podido reafirmarlas según he seguido trabajando.
La importancia de los nombres
Pasamos el día poniendo nombres: a variables, funciones, argumentos, clases, paquetes… Que lo hagamos a cada momento no significa que sea fácil o trivial. Poner nombres es muy difícil y muy importante.
Los nombres son el principal vehículo para hacer nuestro código legible y, en mi opinión, esa debe ser nuestra máxima prioridad.
Algunas buenas prácticas son:
- Elige nombres descriptivos, que se pueden leer y expresen por qué existe ese elemento, qué hace y cómo se usa.
- Usa sustantivos para nombrar clases, objetos y variables y verbos para nombrar métodos.
- Evita alargar los nombres con información que no aporte nada al significado, como palabras genéricas, prefijos o palabras que hagan referencia al contexto cuando el mismo ya está claro.
- Llama de manera similar a las entidades que hacen referencia a un mismo concepto y diferéncialas de aquellas que hagan referencia a otro concepto.
- Si existe un nombre para el concepto que estás usando, porque es un patrón de diseño, un algoritmo conocido o parte del dominio, úsalo. Así facilitarás la comprensión de todo aquel que conozca este concepto.
Un buen nombrado requiere práctica. No te bloquees por ello pero dale la importancia necesaria. Dedica un tiempo a buscar un buen nombre y si no consigues dar con uno, vuelve más adelante para intentar mejorarlo.
Pequeño, más pequeño
Seguro que has oído eso de que las mejores esencias se guardan en frascos pequeños. Piensa en ello cuando programes. Cuando veas que la función que estás implementando o la clase va creciendo pregúntate: ¿estoy manteniendo su esencia? Piensa que vas a volver a leer ese código dentro de un año, seguramente cansado, con otras cosas en la cabeza o con prisas. ¿Podrías mantener la concentración para leerla entera y entender lo que hace? ¿Y si lo tiene que hacer otra persona?
Haz clases pequeñas, métodos pequeños, que se encarguen de hacer una única cosa, de hacerla bien y de no hacer nada más. Mantén el mismo nivel de abstracción para que se lean fácilmente.
Este consejo tan sencillo puede mejorar mucho tu formar de desarrollar. Y aquí termino este punto para predicar con el ejemplo ;)
Sin comentarios
Los comentarios son, en general, una confesión de que no has sabido hacer tu código legible. Suponen un sobresfuerzo que intenta resolver una carencia cometida en el código, cuando ese sobresfuerzo sería mucho más útil dedicarlo a la fuente del problema.
En mi opinión, dificultan más de lo que ayudan, ya que es como si, leyendo un libro, tuvieras que cambiar de idioma en mitad de una página para entender la historia y seguir leyendo. Además es muy sencillo que se pasen por alto o queden desactualizados, por lo que se corre el riesgo de que confundan aún más al desarrollador explicando algo que ya no está ahí.
Por eso, mi norma es no usar comentarios, forzarme a conseguir toda la expresividad a través del código. A veces es tan sencillo como extraer una función con un nombre similar al comentario que tenías en la cabeza, o cambiar el nombre de las variables involucradas. Otras veces es una señal para cambiar el enfoque de la solución, ya que el elegido es muy confuso.
Existen dos tipos de comentarios que sí son necesarios o útiles:
- Javadoc de las APIs públicas: Es importante documentar tus APIs públicas, para que otros desarrolladores puedan usarlas.
- TODOs: Los TODOs son útiles para dejar anotada una idea en una parte del código a la que volverás luego. Con luego me refiero a antes de terminar el día, ya que si no lo has hecho al terminar el día, seguramente no lo hagas al terminar la semana, ni el mes, ni el año…
Cuida tu privacidad
Al aprender a programar parece que, en nuestro afán por enseñarle al mundo nuestras hazañas, tendemos a hacer todas nuestras clases y funciones públicas, sin darnos cuenta de las consecuencias de esta decisión. Cada clase o función que hacemos pública es un compromiso que adquirimos con nuestros usuarios y compañeros que deberemos mantener en el futuro. Recuerda que somos esclavos de nuestras interfaces y dueños de nuestras implementaciones.
También debemos cuidarnos de depender de implementaciones y de la estructura interna de otras clases ya que, aunque no debieran, éstas pueden cambiar rompiendo nuestro código. Sobre esto nos habla la Ley de Demeter, que nos dice que una función de nuestra clase sólo debe llamar a métodos de: la misma clase, miembros de la clase, objetos creados por la función u objetos pasados como parámetro a la función.
Nuestra tendencia debe ser minimizar la visibilidad de nuestras clases y funciones y minimizar también las dependencias con otras clases, de forma que mantengamos la mayor libertad para evolucionar nuestro código.
Tests
Una de las herramientas más potentes para mejorar nuestro código son las pruebas automáticas.
Los tests nos permiten ponernos a prueba, confirmando nuestras intenciones, verificando que el código hace lo que queremos, y cambiando de perspectiva al usar nuestro código desde fuera, evaluando su diseño y observando así sus virtudes y carencias.
Para implementar nuestros tests debemos pensar en el acrónimo FIRST. Los tests deben ser:
- Rápidos (fast), para ejecutarlos continuamente.
- Independientes (independent) de otros, para dirigirnos hacia el código que falla.
- Repetibles (repeatable) en cualquier entorno, para ejecutarlos en cualquier lugar y por cualquier persona con los mismos resultados.
- Autovalidables (self-validating), para indicarnos objetivamente si el test pasa o falla
- Cercanos en tiempo al código que prueba (timely), para retroalimentar nuestro código y permitirnos mejorarlo.
Además, nuestros tests forman parte de nuestro código y tenemos que tener el mismo cuidado y usar los mismos principios de código limpio para que sean legibles y mantenibles.
Pensando en los tests siempre me acuerdo del programa MasterChef y la habitual pregunta: ¿Pero tú has probado el plato?. Parece obvio, pero no lo es. Adquiere el habito de probar tu código para detectar los errores antes que nadie y darte cuenta de las deficiencias de tu diseño, y mejorarás enormemente tus habilidades y tu descanso.
Code smells
Según escribes o lees código, seguro que has notado muchas veces una mala sensación al ver ciertas estructuras o patrones. Esta sensación es la que comúnmente se llama code smell. Es importante entrenar estas sensaciones para poder detectar posibles fuentes de error o de un mal diseño, y corregirlas antes de que causen problemas.
Según ganes experiencia y sigas aprendiendo, aumenta tu catálogo de smells viendo ejemplos y contraejemplos de las tecnologías que usas para que tus sensaciones sean cada vez más fiables y te indiquen puntos de mejora. Apoyate también en tu IDE y en herramientas de análisis estático de código. En el libro Clean Code se muestran muchos de ellos que puedes ir interiorizando.
La regla del Boy Scout
Escribir código limpio es un proceso. No te obsesiones con la perfección, la perfección no existe. Si intentas que el código siga todas y cada una de las prácticas del código limpio desde un primer momento seguramente esto te lleve a la frustración y al bloqueo, sobre todo cuando tengas que programar sobre un código que no sea tuyo.
Mi consejo es que vayas incorporando poco a poco los principios de código limpio en tu día y los tengas en cuenta a la hora de programar. Aplica la regla del Boy Scout: deja el código por el que pasas un poco más limpio que como lo encontraste.
Pero cuidado, ¿recuerdas que el código perfecto no existe? Tenlo en cuenta cuando leas código que ha escrito otra persona. No pienses que algo está mal porque tú lo hubieras hecho de otra manera. Reflexiona antes de cambiarlo y piensa realmente si los cambios mejoran la legibilidad y/o mantenibilidad del código. De igual manera, no tomes como algo personal si alguien cambia tu código. Sé por experiencia que es difícil interiorizarlo, pero tú no eres tú código. Admite consejos, modificaciones y aprende de las diferentes perspectivas que te muestran tus compañeros.
Un lugar perfecto por el que empezar
Recuerdo leer Clean Code como un momento importante en mi carrera profesional y un cambio en la forma de ver el desarrollo. Quizás tiene que ver que fuera el primero pero lo sigo considerando, después de muchos libros ténicos leídos, entre los 5 que más me han impactado.
Me parece el libro ideal para cualquier persona que esté empezando en el mundo de la programación. Por si solo contiene muchos consejos y prácticas sencillas de entender y aplicar que pueden mejorar enormemente tu manera de programar. Además hace referencia a importantes principios de desarrollo (SOLID, DRY, …), técnicas (TDD) y una bibliografía extraordinaria para seguir aprendiendo.
Este libro me puso en el camino para *ser mejor programador. En esta entrada sólo he hecho mención a algunos conceptos que incluye que se me quedaron marcados por su sencillez e importancia, por eso te recomiendo que si no lo has leído todavía lo tengas en cuenta entre tus próximas lecturas.
** Cuando pienses en ser mejor programador sólo debes tener a una persona en mente: a ti mismo. Mejora para sentirte más seguro, para reducir el estrés, para disfrutar más de esta profesión. Sigue estudiando y practicando para poder enfrentarte a problemas más difíciles y conseguir soluciones más eficaces y mantenibles. Y, como he dicho antes, no te obsesiones con la perfección, disfruta del proceso.*

I hesitated a lot about what the topic of my first technical blog post should be, but once it came to mind I can't think of a better option.
Clean Code, by Robert C. Martin, also known as Uncle Bob, was the first book I read for pleasure once I had finished my degree and started working with the goal of becoming a better programmer. I'm sorry I didn't do it sooner, but reading it at that moment — after having some experience and having suffered while coding — made me understand and value it much more.
I remember perfectly the feelings I had while reading it, because all those ideas struck me as common sense. Although, as the saying goes, sometimes common sense is the least common of the senses.
After my first disenchantment with development, it helped me regain my motivation and gather momentum, to understand that things could be done better, that all those concerns and feelings I was experiencing at work made sense and were shared by many others.
What is Clean Code?
The first thing we should ask ourselves is: what is clean code? The concept is quite abstract. At the start of the book, important developers from the industry are asked what it means to them and, in their answers, you can find great ideas concentrated into just a few sentences. Ideas that refer to development principles, patterns and good practices. My favorites for defining what clean code is are:
- It reads like a good book.
- It conveys that it was written by someone who cares about their profession.
- It's elegant and simple. It has the minimum number of elements necessary to do its job, with no embellishments or duplication.
- It's predictable. Each element is in its place and does the expected job.
- It can be handed over to be maintained and evolved by developers other than its author.
- It has automated tests and they all pass.
Principles of Clean Code
Many years have passed since I read this book. I always think about rereading it, but my pile of pending books doesn't give me much of a break. Maybe after writing this post will be a good time.
Even though so much time has passed, there are ideas that stuck with me, because of what they conveyed to me when I read them and because of how I've been able to confirm them as I've kept working.
The importance of names
We spend the day giving names: to variables, functions, arguments, classes, packages… The fact that we do it constantly doesn't mean it's easy or trivial. Naming is very difficult and very important.
Names are the main vehicle for making our code readable and, in my opinion, that should be our top priority.
Some good practices are:
- Choose descriptive names, ones that can be read and that express why that element exists, what it does and how it's used.
- Use nouns to name classes, objects and variables, and verbs to name methods.
- Avoid lengthening names with information that adds nothing to the meaning, such as generic words, prefixes or words that refer to the context when it's already clear.
- Name entities that refer to the same concept in a similar way, and distinguish them from those that refer to a different concept.
- If a name already exists for the concept you're using — because it's a design pattern, a well-known algorithm or part of the domain — use it. That way you'll make it easier for anyone familiar with the concept to understand.
Good naming takes practice. Don't get stuck on it, but give it the importance it deserves. Spend some time looking for a good name and, if you can't come up with one, come back later to try to improve it.
Small, smaller
You've surely heard that the best essences are kept in small bottles. Think about it when you program. When you see that the function or class you're implementing keeps growing, ask yourself: am I preserving its essence? Bear in mind that you're going to read this code again in a year's time, probably tired, with other things on your mind or in a hurry. Could you keep your concentration to read it all the way through and understand what it does? And what if someone else has to do it?
Write small classes, small methods, ones that take care of doing a single thing, doing it well and doing nothing else. Keep the same level of abstraction so they read easily.
This simple piece of advice can greatly improve the way you develop. And I'll end this point here to practice what I preach ;)
No comments
Comments are, in general, a confession that you haven't managed to make your code readable. They represent extra effort that tries to make up for a shortcoming in the code, when that extra effort would be far more useful spent on the source of the problem.
In my opinion, they hinder more than they help, since it's as if, while reading a book, you had to switch languages in the middle of a page to understand the story and keep reading. Besides, it's very easy for them to be overlooked or to become outdated, so there's a risk that they confuse the developer even more by explaining something that's no longer there.
That's why my rule is not to use comments, to force myself to achieve all the expressiveness through the code. Sometimes it's as simple as extracting a function with a name similar to the comment you had in mind, or renaming the variables involved. Other times it's a sign that I should change the approach to the solution, because the one I chose is very confusing.
There are two types of comments that are necessary or useful:
- Javadoc for public APIs: It's important to document your public APIs so that other developers can use them.
- TODOs: TODOs are useful for jotting down an idea in a part of the code you'll come back to later. By later I mean before the end of the day, because if you haven't done it by the end of the day, you probably won't do it by the end of the week, the month, or the year…
Mind your privacy
When learning to program, it seems that, in our eagerness to show the world our feats, we tend to make all our classes and functions public, without realizing the consequences of that decision. Every class or function we make public is a commitment we take on with our users and colleagues that we'll have to maintain in the future. Remember that we are slaves to our interfaces and masters of our implementations.
We must also be careful about depending on the implementations and internal structure of other classes since, although they shouldn't, these can change and break our code. The Law of Demeter tells us about this: a function of our class should only call methods of the same class, members of the class, objects created by the function, or objects passed as parameters to the function.
Our tendency should be to minimize the visibility of our classes and functions, and also to minimize dependencies on other classes, so that we keep the greatest freedom to evolve our code.
Tests
One of the most powerful tools for improving our code is automated testing.
Tests let us put ourselves to the test, confirming our intentions, verifying that the code does what we want, and shifting our perspective by using our code from the outside, evaluating its design and thus observing its strengths and shortcomings.
To implement our tests we should think about the acronym FIRST. Tests should be:
- Fast, so we can run them continuously.
- Independent of one another, so they point us toward the failing code.
- Repeatable in any environment, so they can be run anywhere and by anyone with the same results.
- Self-validating, so they tell us objectively whether the test passes or fails.
- Timely, written close in time to the code they test, so they feed back into our code and let us improve it.
Besides, our tests are part of our code and we have to take the same care and apply the same clean code principles so that they're readable and maintainable.
Thinking about tests, I always remember the show MasterChef and its usual question: But have you actually tasted the dish?. It seems obvious, but it isn't. Get into the habit of testing your code to spot the bugs before anyone else and to notice the deficiencies in your design, and you'll greatly improve your skills and your peace of mind.
Code smells
As you write or read code, you've surely noticed many times a bad feeling when seeing certain structures or patterns. This feeling is what's commonly called a code smell. It's important to train these feelings so you can detect possible sources of error or bad design, and fix them before they cause problems.
As you gain experience and keep learning, expand your catalog of smells by looking at examples and counterexamples of the technologies you use, so that your instincts become more and more reliable and point you to areas for improvement. Lean also on your IDE and on static code analysis tools. The book Clean Code shows many of them that you can gradually internalize.
The Boy Scout Rule
Writing clean code is a process. Don't obsess over perfection; perfection doesn't exist. If you try to make your code follow each and every clean code practice from the very start, that will surely lead you to frustration and paralysis, especially when you have to program on code that isn't yours.
My advice is to gradually incorporate the clean code principles into your day and keep them in mind when programming. Apply the Boy Scout Rule: leave the code you touch a little cleaner than you found it.
But be careful — remember that perfect code doesn't exist? Keep it in mind when you read code that someone else has written. Don't assume something is wrong just because you would have done it differently. Reflect before changing it and really think about whether the changes improve the readability and/or maintainability of the code. Likewise, don't take it personally if someone changes your code. I know from experience that it's hard to internalize, but you are not your code. Accept advice and modifications, and learn from the different perspectives your colleagues show you.
A perfect place to start
I remember reading Clean Code as an important moment in my professional career and a change in the way I see development. Maybe it has to do with it being the first one, but even after many technical books read, I still consider it among the 5 that have had the biggest impact on me.
I think it's the ideal book for anyone starting out in the world of programming. On its own it contains many pieces of advice and practices that are easy to understand and apply and that can greatly improve the way you program. It also refers to important development principles (SOLID, DRY, …), techniques (TDD) and an extraordinary bibliography to keep learning.
This book set me on the path to *becoming a better programmer. In this post I've only mentioned a few of the concepts it includes that stuck with me for their simplicity and importance, which is why I recommend that, if you haven't read it yet, you keep it in mind among your next reads.
** When you think about becoming a better programmer, there's only one person you should have in mind: yourself. Improve to feel more confident, to reduce stress, to enjoy this profession more. Keep studying and practicing so you can tackle harder problems and achieve more efficient and maintainable solutions. And, as I said before, don't obsess over perfection — enjoy the process.*