Google Analytics

jueves, 21 de enero de 2010

Programación orientada a objetos más legible

El año pasado llegó a mis manos casi por casualidad un libro titulado "The Thoughtwors Antology". Mirandolo por encima, uno de sus capítulos, escrito por Jeff Bay, me llamó la atención porque daba una serie de reglas para mejorar la calidad de nuestro código orientado a objetos en muy pocas páginas. A mi me gustaría comentar algunas de estas reglas en mi blog porque considero que son bastante útiles.

Esto no quiere decir que podamos evitar la lectura de libros (de gran calidad) dedicados al tema como puede ser "Clean code", pero nos permite tener una visión general para todos aquellos que no seamos expertos en la programación orientada a objetos.

Un nivel de indentación por método.

Dicho así de rápido y fuera de contexto puede resultar una regla un poco dura, pero en realidad hace referencia a la necesidad de tener métodos cohesivos y que realicen una única tarea. Una de las mejores métricas que he conocido en mi breve vida de desarrollador de software es esta, porque cuando un mismo método tiene más de dos niveles de anidamiento es que está haciendo algo más de lo que debería (esto no quiere decir que se cumpla en el 100% de las veces).

No hacer uso de la palabra reservada "else".

En mi experiencia de estudiante lo más importante de las prácticas es que funcionen, siempre tiene algo de importancia la calidad del código pero no se mira con mucho detalle (dependerá de la asignatura y el profesor). Pero cuando empiezas a trabajar, muchas empresas también buscan que el código sea sencillo y se entienda en una sola pasada, principalmente porque en el código trabaja más gente a parte de tí. Los bloques condicionales son una de las estructuras que más oscurecen el código fuente, por lo que es necesario simplificarlos lo mejor posible.

Pongamos el ejemplo siguiente.


public void deleteDocument(String docId) {
   Document document = getDocument(docId);
   if (document != null)
      database.delete(document);
   else
      throw new BlackboardException(...);
}

Utilizando esta regla podemos refactorizar al siguiente bloque, que en general resultará más sencillo de leer y por lo tanto de saber cual es su función (aunque el propio nombre del método debería aclararlo).


public void deleteDocument(String docId) {
   Document document = getDocument(docId);
   if (document == null)
      throw new BlackboardException(...);

   database.delete(document);
}

Hay algunos autores que incluso recomiendan evitar el uso de los bloques condicionales, haciendo uso de las propiedades de los objetos. Intenta hacer algunos ejercicios verás como la calidad de tú código mejora drásticamente.

Envolver todas las primitivas y strings.

Esta, en mi opinión, es una regla un poco controvertida, pero es igual de cierto que es una práctica común en Domain-Driven Design (DDD) porque hace los conceptos explícitos. Hay casos en los que el uso de primitivas se entiende perfectamente bien, pero hay casos en los que el uso de objetos valor (objetos que envuelven a la primitiva, en general extendiendola) puede aclarar el modelo de dominio y además hacer que el modelo se pueda evolucionar más facilmente en el futuro.

Utilizar un solo punto (.) por línea.

Aunque lo intento evitar en la medida de lo posible, es muy normal encontrar en muchos lugares de mi código cosas como ...



...
comprobarCodigoPostal(persona.getDireccion().getCodigoPostal());
...

Para mucha gente será obvio que no se está haciendo uso de forma correcta de la abstracción de los objetos. Sería más lógico y mucho más claro tener algo como ...



...
comprobarDireccion(persona.getDireccion());
...
comprobarCodigoPostal(direccion.getCodigoPostal());
...

Quizás el ejemplo no es el más claro del mundo, pero espero que se aprecie que evitando la utilización de más de una referencia por línea, el código es mucho más sencillo y manejable, además de representar su funcionalidad a primera vista.

No usar abreviaciones.

Robert C. Martin escribe en su libro que hay que llamar a las cosas por su nombre, y esto es básicamente lo que quiere decir esta regla.

Revisando mis prácticas de Universidad he observado la tendencia a abreviar todos los nombres de instancias o de métodos, en parte adoptado de un modelo de programación más funcional. Lo que ocurre es que cuando miro dichas prácticas unos años más tarde, ya no se lo que siginifican algunas variables llamadas t o x porque ya no tengo en la cabeza el modelo que estaba tratando en ese momento, pero aún puede resultar peor para una persona que jamas haya trabajado en el dominio del problema que estaba resolviendo.

Mantener las clases lo más pequeñas posible.

En esta regla Jeff Bay indica que las clases no deben tener más de 50 líneas de código y los paquetes no deben tener más de 10 ficheros. No creo que sea un regla que haya que seguir al pie de la letra, supongo que una clase puede tener 60 líneas sin que signifique que no es cohesiva. Pero es bueno que la usemos para preguntarnos si estamos siguiendo el camino correcto, porque una clase cohesiva se limita a una sola cosa y por lo tanto no debería necesitar una gran cantidad de líneas de código para realizar dicha cosa.

Nota: Todas estas reglas pueden ser aplicadas en gran cantidad de ocasiones, pero hay que tener claro que habrá momentos en los que no nos conviene o simplemente no podemos hacerlo porque el problema es demasiado complejo, por ejemplo.

3 comentarios:

kkk dijo...
Este comentario ha sido eliminado por un administrador del blog.
Sergio dijo...

Hola Yeray, excelente resumen de buenas prácticas. No entiendo porque la gente se complica tanto a la hora de escribir algunas "lineas de código". En su momento ley estos dos libros (no complemante) Refactoring: Improving the Design of Existing Code y Refactoring to Patterns. Ambos libros los puedes encontrar en Amazon y está bastante bien, para aquellos que se preocupen de la "elegancia del codigo".

Por cierto, felicidades por el blog.

Yeray Darias Camacho dijo...

Muchas gracias Sergio, he ojeado ambos libros que comentas y son bastante buenos, me encantaría que algún día fuesen una referencia obligatoria en la universidad.