La programación mediante cortar y pegar es muy común, pero es una forma de degenerada de reutilización de software la cual crea pesadillas a la hora del mantenimiento. Proviene de la idea de que es más fácil modificar código existente que hacerlo desde cero. Esto es generalmente cierto y representa un buen instinto de software. Sin embargo, la técnica puede ser usada de manera excesiva.
Generalidades
Este antipatrón se identifica por la presencia de una gran cantidad de código desperdigados a lo largo del proyecto. Usualmente, un proyecto posee programadores que están aprendiendo cómo desarrollar software siguiendo ejemplos de desarrolladores más experimentados.
Sin embargo, ellos están aprendiendo mediante la modificación de código que se ha demostrado que funciona en situaciones similares y, potencialmente, la personalización permite soportar nuevos tipos de datos o un comportamiento ligeramente modificado. Esto crea código duplicado, el cuál puede tener consecuencias positivas a corto plazo, como una aceleración de las métricas de código, las cuales pueden ser usadas en evaluaciones de rendimiento.
Síntomas y consecuencias
- Los mismos errores se repiten a lo largo de todo el software a pesar de muchos arreglos locales.
- Se incrementan las líneas de código sin añadir verdadera productividad.
- Revisiones e inspecciones de código son extendidas innecesariamente.
- Se torna difícil localizar y corregir todas las instancias de un error en particular.
- Este antipatrón conlleva tener excesivos costos de mantenimiento de software.
- Los defectos del software se replican por todo el sistema.
Causas típicas
- Se necesita un gran esfuerzo para crear código reutilizable y las organizaciones hacen más hincapié en ganancias a corto plazo que en inversión a largo plazo.
- La organización no promueve componentes reusables y la velocidad de desarrollo eclipsa todos los demás factores de evaluación.
- La inexistencia de conocimiento de abstracción entre los desarrolladores es a menudo acompañado por un pobre entendimiento de la herencia, composición y otras estrategias de desarrollo.
- Los componentes reusables, una vez creados, no son suficientemente documentados o hechos disponibles para los desarrolladores.
- El síndrome "Aun no está hecho" abunda en el entorno de desarrollo.
- La inexistencia de previsión o proactividad entre los equipos de desarrollo.
Solución
La clonación ocurre frecuentemente en entornos dónde el reuso de tipo white-box es la forma predominante de extensión del sistema. En estos casos, los desarrolladores extienden los sistemas a través de la herencia. Ciertamente, la herencia es una parte esencial del desarrollo orientado a objetos, pero tiene severos inconvenientes en sistemas grandes.
Primero, derivar y extender un objeto requiere cierto conocimiento de cómo el objeto está implementado así como las restricciones y patrones de uso indicados por las clases base heredadas. Muchos lenguajes orientados a objeto imponen algunas restricciones, tipos de extensiones pueden ser implementados en una clase derivada y llevar a un uso inadecuado de derivación.
Además, por lo general, el reuso por caja blanca es posible solamente en tiempo de compilación de la aplicación así como todas las subclases deben estar completamente definidas antes de que la aplicación sea generada.
Por otro lado, el reuso por caja negra (black-box) tiene un diferente conjunte de ventajas y limitaciones. Frecuentemente es una mejor opción para la extensión de objetos en sistemas de moderado y gran tamaño. Con este reuso un objeto es usado tal cual es, usando su interfaz pública. El cliente no tiene permitido alterar cómo el objeto está implementado.
El beneficio clave del reuso de caja negra es que, con el soporte de herramientas, tales como lenguajes de definición de interfaces, la implementación de un objeto puede ser llevada a cabo independientemente de la interfaz del objeto. Esto posibilita a un desarrollador tomar la ventaja de un enlace tardío mediante la asignación de una interfaz con su implementación en tiempo de ejecución. Los clientes puede escritos en base a una interfaz de objeto estático y aun beneficiarse por el tiempo mediante servicios más avanzados que soportan una idéntica interfaz de objeto.
La diferencia entre la reutilización de caja blanca y caja negra, es la misma que hay entre la programación orientada a objetos (OOP) y la programación orientada a componentes (COP), dónde la derivación de clases de tipo caja blanca es la firma tradicional de OOP y el enlace en tiempo dinámico de interfaces a una implementación es un elemento básico en COP.
Reestructurar el software para reducir o eliminar clones requiere la modificar código para enfatizar el reuso de caja negra de los segmentos duplicados del código.En le caso en que la progrmación mediante Cut and paste ha sido usada extensivamente a lo largo de la vida del proyecto, el método más efectivo de recuperar la inversión es refactorizar el código base en librerías reusables o en componentes que hagan foco en el reuso mediante caja negra de la funcionalidad.
Si se lleva a cabo como un único proyecto, este proceso de refactoring es generalemente difícil, prolongado y costoso. Requiere de un arquitecto para supervisar y ejecutar el procesos, y mediar en las discuciones sobre las ventajas y limitaciones de las diferentes maneras de extender los módulos.
Un refactoring efectivo para eliminar el código repetido involucra tres etapas: code mining, refactoring y configuration managment. La primera es la identificación sistemática de las múltiples versiones de los mismos segmentos de código. La segunda etapa involucra el desarrollo de una versión estándar de dichos segmentos y reinsertarlo en el código base. Finalmente, configuration managment son un conjunto de políticas elaborado para ayudar y prevenir de futuras ocurrencias de este antipatrón. En su mayor parte, esto requiere de políticas de supervisión y detección (inspecciones de código, revisión, validación) además de los esfuerzos educativos.
0 comentarios:
Publicar un comentario
Muchas gracias por leer el post y comentarlo.