Los Principios de la Buena Programación

Encuentro en estos días el post The Principles of Good Programming, de Christopher Diggins.

Christopher Diggins is a software developer and freelance writer. Christopher loves programming, but is eternally frustrated by the shortcomings of modern programming languages. As would any reasonable person in his shoes, he decided to quit his day job to write his own ( www.heron-language.com ). Christopher is the co-author of the C++ Cookbook from O’Reilly. Christopher can be reached through his home page at www.cdiggins.com.

Me gustaría transcribir en mis palabras la lista de principios de ese post. Veamos:

DRY – Don’t repeat yourself – No repetirse a sí mismo. Podría remontarme a Ada Lovelace y su idea de rutinas para encontrar el germen de este principio. Funciones, métodos, clases son todos artefactos que fueron apareciendo en la historia de la programación para evitar la repetición. Ver http://en.wikipedia.org/wiki/Don%27t_repeat_yourself

Abstraction Principle – Principio de Abstracción. Es una forma de llegar al DRY de arriba. “Cada pieza de funcionalidad significativa en un programa debe ser implementada en un sólo lugar del código fuente”. Ver http://en.wikipedia.org/wiki/Abstraction_principle_(programming 

KISS (Keep it simple, stupid) – Manténgalo simple, estúpido! Tal vez mi principio preferido. Ante tanta complejidad accidental, temas de tecnologías, frameworks y librerías, la mejor solución a un problema es la más simple. Menos código, menos bugs. Ver http://en.wikipedia.org/wiki/KISS_principle

Avoid Creating a YAGNI (You aren’t going to need it) – Evitar crear algo que no vamos a necesitar. Es común tratar de ver el futuro y comenzar a crear abstracciones que todavía no estamos usando. Una de las razones por las que prefiero trabajar con TDD (Test-Driven Development) es que nos permite alcanzar éste y otros principios (como el KISS y los que siguen abajo) de una forma natural. Muchas veces digo: “No hay que cruzar al puente antes de llegar al puente”. Ver http://en.wikipedia.org/wiki/YAGNI

Do the simplest thing that could possibly work – Haga lo más simple que funcione. Siempre hay que preguntarse ¿qué es lo más simple que tengo que escribir para que esto funcione? De nuevo, TDD me lleva a este principio. Al no introducir complejidad a cada paso, vamos manteniéndonos en el camino de la simplicidada. Ver http://c2.com/xp/DoTheSimplestThingThatCouldPossiblyWork.html

Don’t make me think – No me haga pensar. Hay un libro de Steve Krug con este título (Don’t Make Me Think: A Common Sense Approach to Web Usability, 2nd Edition) Así como la interfaz tiene que ser algo que no nos haga pensar ¿y ahora, cómo lo hago? el código que escribamos tiene que ser consumible de la misma forma: evitar lo “tricky”, los nombres de las funciones deben declarar claramente lo que hacen, etc. Por ejemplo, a veces veo código Fluent que hay que hacer un curso en la NASA para ver qué hacen, de tanto lambda que aparece en los parámetros ;-). Pero tengo que reconocer que pueden ser útiles una vez uno entiende el concepto.

Open/Closed Principle – Principio Abierto/Cerrado. Uno de los principios S.O.L.I.D. (ver http://en.wikipedia.org/wiki/SOLID_%28object-oriented_design%29) Entidades de software (clases, módulos, funciones) deben estar abiertas a la extensión, pero cerradas a la modificación. Hay que escribir clases, no para que otros las modifiquen, sino para que otras las usen y extiendan.

Write Code for the Maintainer – Escriba código para el que va a mantenerlo. Yo diría: escriba código para sí mismo dentro de seis meses. Otro punto donde TDD me ayuda. No hay que escribir código “cool”, hay que escribir código claro que haga cosas “cool”. Muchas veces veo código brillante, pero inmantenible. Tomemos nuestro tiempo, y pongamos “algo de amor” en el código ;-). Dice el post que comento: “Escriba el código como si el que tuviera que mantenerlo fuera un sicópata asesino que conoce donde vives” Ver http://c2.com/cgi/wiki?CodeForTheMaintainer

Principle of least astonishment – Principio del menor asombro. Se aplica en general a la interfaz de usuario, pero también se puede aplicar al código. El texto del código no debe provocar sorpresa. Ejemplo: el nombre de una función debería corresponder con lo que hace. Hasta la indentación del código y las convenciones ayudan. Ver http://en.wikipedia.org/wiki/Principle_of_least_astonishment

Single Responsability Principle – Principio de Responsabilidad Unica. Un componente de código (clase, función) debe ejecutar una única y bien definida tarea. Otro de los principios S.O.L.I.D. Ver http://en.wikipedia.org/wiki/Single_responsibility_principle

Minimize Coupling – Minimizar el acoplamiento. Cada componente (bloque de código, clase, función, etc.) debe minimizar las dependendencias de otros componentes. Por ejemplo, usar lo menos posible variables en común. Cuando un componente A tiene que usar el componente B, debe tratar de conocer lo menos posible de B: por ejemplo, sólo consumir lo necesario de su funcionalidad, y no entrar en temas como crear a B (de ahí el uso de inyección de dependencias). No hacer cosas como B.propiedad.propiedad2.metodo() (un caso de la ley de Demeter de más abajo). El minimizar el acoplamiento trabaja junto con el maximizar la cohesión. Ver http://en.wikipedia.org/wiki/Coupling_%28computer_programming%29

Maximize Cohesion – Maximizar Cohesión. Un componente debe tener funcionalidad altamente relacionado. Evitar implementar en un componente dos funcionalidades que no están relacionadas, cumpliendo tareas que no tienen relación. Ver http://en.wikipedia.org/wiki/Cohesion_%28computer_science%29

Hide Implementation Details – Ocultar Detalles de Implementación. Ejemplo, no exponer variables de estado interno: preferir propiedades controladas o mejor, directamente métodos. Concentrarse en exponer lo que los demás van a consumir, antes que los detalles de cómo cumplimos con nuestra tarea. Esto permite llegar a cambiar la implementación sin afectar al resto del sistema. En lenguajes tipados como C# y Java, se puede llegar a algo de esto consumiendo interfaces definidas. http://en.wikipedia.org/wiki/Information_Hiding

Law of Demeter – Ley de Demeter. Los componentes de código deben comunicarse con los directamente relacionados. Usar B si se referencia desde A, pero evitar usar B.C.D.metodoE(). A se relaciona directamente con B si lo recibe en su constructor, o como parámetro de un método. También se puede tomar como “directo” la funcionalidad heredada de una superclase. Ver http://en.wikipedia.org/wiki/Law_of_Demeter

Avoid Premature Optimization – Evitar la Optimización Prematura. Otro caso de “no hay que cruzar el puente hasta llegar al puente”. Hay que evitar pensar en optimizar código, si apenas lo estamos armando. Ir armando el código de tal forma que podamos refactorizarlo, cambiar implementación, concentrar los cambios en pocos lados (todo esto ayudado por los otros principios, y TDD) para cuando llegue el tiempo de optimizar (si es que llega). Para optimizar, hay que medir, no intuir. "We should forget about small efficiencies, say about 97% of the time: premature optimization is the root of all evil" – Donald Knuth. http://en.wikipedia.org/wiki/Program_optimization

Code Reuse is Good – El Reúso de Código es Bueno. Aprovechar código ya escrito, si es buen código (esperamos que cumpla los otros principios). Mejora el tiempo de desarrollo, y si es código ya usado y probado, mejora el resultado. Ver http://en.wikipedia.org/wiki/Code_reuse

Separation of Concerns – Separación de Preocupaciones. Un componente no debe ocuparse de dos o más tareas, especialmente si tienen poca relación no accidental entre sí. Por ejemplo, el manejo de la autorización a ejecutar un método debería quedar, en lo posible, fuera del código de ese método. Ver http://en.wikipedia.org/wiki/Separation_of_concerns

Embrace Change – Abraza el cambio. El cambio es una constante en el desarrollo de software: cambio en los requerimientos, la funcionalidad, la tecnología, la evolución de un sistema exitoso. No hay que luchar contra el cambio, sino trabajar para estar preparado para él. Programación ágil, TDD, integración continua, Scrum, iteraciones cortas, revisión en cada iteración, son todas prácticas que soportan este principio. Ver Extreme Programming Explained: Embrace Change (2nd Edition)

Alguno más? Comentarios? Supongo que puedo escribir algún post de cada uno, con algún ejemplo. Veremos! ;-)

Nos leemos!

Angel “Java” Lopez
http://www.ajlopez.com
http://twitter.com/ajlopez

This entry was posted in 10549, 12081, 12114, 3463. Bookmark the permalink.

3 Responses to Los Principios de la Buena Programación

  1. Juan Nallar says:

    Creo que “Code Reuse is Good” es lo mismo que “DRY”

  2. Me encantó, muy bueno.

    Muchísimas gracias.

    Saludos

  3. anonimo says:

    Chapó

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>