Tuesday, November 22, 2011

Herramientas de Metrica

Checkstyle: 
 Comprueba normas de estilo a lo largo del código JAVA de un proyecto. Entre otras, comprueba:
  • Que los artefactos contengan comentarios JAVADOC.
  • Convenciones de nombrado.
  • Límites de longitud en líneas y parámetros.
  • La presencia de cabeceras.
Destacan también las posibilidades de detección de secciones de código duplicadas y medidas de complejidad.

PMD:
Un analizador de código JAVA utilizado para detectar errores comunes, código muerto, sentencias demasiado complejas, medidas de complejidad ciclomática y código duplicado, así como detección de patrones de código simplificable, substituíble o mejorable.

Findbugs:
Un analizador estático de bytecodes que detecta bugs potenciales.

Clover:
Una herramienta de cobertura de código. Una gran ventaja que aporta es que permite filtrar los tests de manera que solo se lanzan aquellos que implican código modificado desde la última ejecución.

Sonar:
Plataforma online de presentación de métricas de calidad del software. Se basa en las herramientas citadas anteriormente. Genera multitud de informes.







Monday, November 21, 2011

Los Principios de Código

Eliminación de redundancias. DRY/DIE: 
 DRY:  Don't Repeat Yourself
 DIE: Duplication Is Evil.

Una unidad de conocimiento debe tener una única representación dentro de un sistema. Cuando se cumple correctamente la modificación de un elemento no implica un cambio en elementos que no están relacionados con él. Como todo en este mundo debe interpretarse dentro del marco del sentido común, existen autores que se oponen al DRY absoluto dado que sugieren que la repetición añade más verbalidad al código, por ejemplo en los tests la repetición permite que el código sea más semejante a un guión.  En general DRY/DIE a nivel de algoritmos y lógica de estados es absolutamente recomendable, tal cual ocurre en una redacción en lenguaje no automático.

Principios SOLID:
Un objetivo principal de agilidad a nivel de código es generar código legible, extensible y fácil de mantener. Deteminar qué es buen código no es tarea simple y se han desarrollado varias técnicas para determinar su calidad, entre ellas los criterios SOLID son muy conocidos. Veamos en qué consisten:

S: (SRP) Principio de Única Responsabilidad.
O: (OCP) Principio de Apertura/Cierre.
L: (LSP) Principio de Substitución de Liskov.
I: (ISP) Principio de Segregación de Interfaz.
D: (DIP) Principio de Inversión de Dependencia.



S: (SRP) Principio de Única Responsabilidad.
Una entidad en un sistema debe ocuparse de una y solo una responsabilidad, de lo contrario debe plantearse la división en varias entidades. En principio esto aumenta el bajo acoplamiento y aumenta la cohesión dado que el reparto de responsabilidades es una buena técnica de dispersión y concentración de código.
 
O: (OCP) Principio de Apertura/Cierre.
 En general es deseable que una entidad pueda extenderse de manera que acepte nuevas variantes de comportamiento o estructura sin necesidad de modificar el código original. Estar "cerrado" para la modificación y "abierto" a la extensión implica que el código no está sujeto a modificaciones que pongan en riesgo sistemas que lo usan actualmente. Es un principio básico de la reutilización.


L: (LSP) Principio de Substitución de Liskov.
 Un principio bastante teórico:
   Sea p(x) una propiedad probable de los objetos x de tipo T. Entonces p(x) debe ser probable para los objetos y de tipo S, siendo S un subtipo de T.

Ahí queda eso... simplemente el principio viene a indicarnos que en una jerarquía de objetos bien diseñada siempre podremos substituir los objetos del tipo superior por una de sus herencias. Como un ejemplo básico si tenemos un sistema que funciona con objetos del tipo Animal ese sistema debería aceptar directamente trabajar con objetos del tipo Pollo o Perro. Conseguir esto no es tarea fácil y mucho menos garantizarlo, en principio es necesario fijar que los métodos de las clases heredadas sean iguales en argumentos y en tipo de retorno y no lanzar excepciones nuevas o distintas (los lenguajes actuales fuerzan a ello, el principio se enunció en 1987 y estamos en el año 2011). El contrato que siguen los subtipos debe también cumplir que las precondiciones no sean más fuertes que las de la clase que heredan, las postcondiciones no ser más débiles y que se respeten las invariantes, lo cual es absolutamente lógico ¿qué no lo es?

I: (ISP) Principio de Segregación de Interfaz.
 Una interfaz debe mantenerse pequeña, es más fácil cumplir contratos pequeños que contratos enormes, por tanto una interfaz grande debe segregarse en variar interfaces más pequeñas. Esto permite que los objetos que se comunican con un sistema lo hagan mediante una interfaz reducida que aclara cuál es su rol, un cliente no debe estar forzado a depender de métodos que no va a utilizar.


D: (DIP) Principio de Inversión de Dependencia y Métodos de Inversión de Control.
  • Los módulos de niveles superiores no deben depender de los módulos de niveles inferiores. Ambos deben depender de abstracciones.
  • Las abstracciones no deben depender de los detalles. Los detalles deben depender de las abstracciones.
Vaya, vaya... bocadillo de caballa. Para el que recuerde la frase popularizada por Bruce Lee, ¡gran maestro del Kung Fu!, "Be water my friend", los maestros de código en su iluminanción suelen decir: "Mantente abstracto". Gran concepto que va mucho más allá del código y probablemente del Kung Fu, si es que eso es posible.

Un módulo (superior) no debe depender directamente de otro (inferior), de lo contrario la reusabilidad del módulo (superior) se verá muy afectada. Aunque parezca lo contrario solucionar esto no suele ser complicado, si trabajoso, un módulo debe depender de una interfaz abstracta, si otro módulo quiere comunicarse con aquel debe cumplir o acomodarse a la interfaz sugerida.  
 --------------------------- 

Principio de Simplicidad (KISS):

Tal como le indicaba el detective Rick al pianista en la película Casablanca: "Tócala otra vez Sam", el principio KISS viene a decir: "Keep it Simple Sam", variantes posteriores de este enunciado llevaron a versiones algo más agresivas como "Keep It Simple, Stupid" que en mi criterio deben evitarse en toda alegación de mejora de un diseño realizado, no llame estúpidos a sus compañeros a no ser que tenga absoluta certeza de ello, y si es así, tampoco es recomendable. Otra opción es eliminar la coma, con lo que la interpretación conveniente sería: Mantenlo estúpidamente simple, mucho más socialmente correcta, dónde va a parar.

Como otros muchos principios fácil es decirlo pero no hacerlo:

"Un objetivo del diseño de un sistema es que sea lo más simple posible, evitando toda complejidad innecesaria".