Refactorizar Codigo
Introducción
• La evolución de un sistema software conlleva cierto grado de
deterioro de su estructura.
• El mantenimiento se centra más en la corrección de bugs y en
la inclusión de nuevas funcionalidades que en el seguimiento y
la mejora de su arquitectura y diseño.
• La malas prácticas de diseño, causadas a menudo por la
inexperiencia, el conocimiento insuficiente o la urgencia,
originan design smells (“malos olores en el diseño”):
problemas en la estructura de un sistema, que no producen
errores de compilación o de ejecución, pero que afectan
negativamente a los factores de calidad del software
Qué es refactorización?
• "Refactorizar es una técnica disciplinada para reestructurar
una porción de código, alterando su estructura interna sin
modificar su comportamiento externo.” Martin Fowler
• Cada transformación llamada refactoring se hace de a
poco.
• Una secuencia de transformaciones puede
producir una reestructuración significativa.
Proceso de mejora continua
• El refactoring se considera un proceso de mejora continua.
Debido a que se debe ir perfeccionando el software iteración
por iteración. Estos cambios deben ser muy pequeños, a tal
punto que pueda ser controlado sin miedo a generar errores.
Objetivo del refactoring
• Es realizar y mantener el código limpio y bien estructurado,
permitiendo una mejor lectura del código para comprender
que es lo que se está realizando.
¿Por qué se debe Refactorizar el
código?
• Calidad
• Crear un código de calidad es un código sencillo y bien estructurado, que cualquiera pueda leer y
entender sin necesidad de haber participado dentro del equipo de desarrollo.
• Eficiencia:
• El esfuerzo que se debe realizar para mantener un código limpio, bien estructura, sin duplicación de
código y con diseño simple se verá recompensado cuando se deba realizar tareas de mantenimiento a la
aplicación, así como para la detección y corrección de errores y la creación de nuevas funcionalidades.
• Diseño Evolutivo en lugar de Gran Diseño Inicial:
• En muchas ocasiones los requisitos al principio del proyecto no están suficientemente especificados y
debemos abordar el diseño de una forma gradual.
• Cuando tenemos unos requisitos claros y no cambiantes un buen análisis de los mismos puede originar un
diseño y una implementación brillantes, pero cuando los requisitos van cambiando según avanza el
proyecto, y se añaden nuevas funcionalidades según se le van ocurriendo a los participantes o clientes, un
diseño inicial no es más que lo que eran los requisitos iniciales.
• Refactorizar nos permitirá ir evolucionando el diseño según incluyamos nuevas funcionalidades, lo que
implica muchas veces cambios importantes en la arquitectura, añadir cosas y borrar otras.
• Evitar la Reescritura de código:
• Refactorizar es más beneficio que reescribir.
• Nunca es bueno empezar de cero a pesar de que el código en el que se encuentra no es entendible y
desorganizado.
• Mejor opción refactorizar y empezar a usar ese código.
Bad Smell
• Un “Bad Smell” es un indicio de que existe código de poca
calidad.
• Martin Fowler define el Bad Smell de la siguiente forma:
“Un método parece estar más interesado en otra clase que la
propia clase a la que pertenece”.
Bad Smells
• Código Duplicado:
• Poseer la misma estructura de código en dos o más lugares es señal de que
ese código necesita refactorización.
• Si se realiza un cambio en alguno de esos lugares, probablemente sea
necesario realizar ese cambio en los otros lugares, pero muchas veces no se
suele acordar de realizar esos cambios.
• Métodos Largos:
• Métodos largos se deben descomponer para una mayor claridad y facilidad
de mantenimiento.
• Clases grandes:
• Esto es indicio de que las clases deben estar haciendo demasiado,
usualmente tienen gran número de variables instanciadas. Mucha veces
algunas de estas variables pueden ser agrupadas o en otros casos solamente
son utilizadas ocasionalmente.
• Lista de parámetros larga:
• Una lista larga de parámetros muchas veces es difícil de entender. No
necesariamente se deben pasar todos los parámetros únicamente los
necesarios.
Bad Smells
• Cambio divergente:
• El código debe estar estructurado para realizar cambios de forma
sencilla.
• Si una clase es cambiada de diferentes formas por diferentes razones,
mucha veces es mejor dividir la clase en dos, una clase específica para
cada tipo de cambio que se presente.
• Cirugía de la escopeta:
• Es el opuesto al cambio divergente.
• Si un programa requiere muchos cambios pequeños en diferentes
clases, y se hace muy difícil localizar todos los lugares exactos que se
necesitan cambiar. Es mejor que todos esos lugares afectados agrupados
dentro de una sola clase.
• Envidia de las funcionalidades:
• Cuando un método dentro de una clase está más interesado en los atributos, usualmente en
los datos de otra clase que de su propia clase. Este método estaría más confortable en la otra
clase.
• Declaración de “Swtich”:
• Muchas veces los “Switch” tienden a ocasionar duplicación.
• Se pueden encontrar declaraciones de “switch” similiares dispersar a lo largo del programa.
• Si se debe pasar un nuevo valor, se deben chequear todas las declaraciones de “switch”.
• Las clases y los poliformismos suelen ser lo más apropiado para resolver esta situación.
• Obsesión por los primitivos:
• Algunas veces vale la pena cambiar los tipos de datos primitivos en clases simples que
realicen de forma más clara esa tarea.
• Comentarios:
• El comentario miente, el código no.
• No es recomendable reemplazar el código mal escrito por comentarios. Por lo tanto se debe
mejorar el código.
•
• Clases flojas
• Clases que no hacen un trabajo util debe ser eliminadas
• Generalidad especulativa
• Frecuentemente se diseñan clases y métodos para hacer cosas
que en realidad no se necesitan
• Campos temporales
• Puede ser confuso cuando atributos de una clase son usados
ocacionalmente.
• Cadena de mensajes
• Cuando un cliente pide un objeto de otro objeto, luego qué se
pidio del otro objeto?
• Hombre medio
• La delegacion es frecuentemente util, pero aveces puede ir muy
lejos.
• Si una clase actua como delegada pero ejecuta trabajo extra no
util, podria ser posible eliminarla de a jerarquía
• Data class
• Clases que solo tienen datos y metodos de acceso, pero no un
comportamiento real.
• Si el dato es publico hazlo privado.
• Legado rechazado
• Si una subclase no quiere o no necesita todo el comportamiento
de la clase base, quiza la jerarquía de clases este equivocada.
• El sistema debe seguir funcionando a 100% después de cada
refactorización (pequeña), reduciendo la posibilidad de que el
sistema se dañe gravemente durante la restructuración.
Principios
• Escribir código simple
• Hacerlo simple no es fácil
• Einstein
• Escribir código claro, que se entienda
• Escribir código breve corto, no sentencias largas (clases,
programas cortos).
• No escribir código que no sea necesario
• Está mi codigo haciendo una cosa, y una cosa bien?
Smell bad
• Clever code
• Mejor escribir codigo claro, simple en lugar de inteligente
• Métodos largos
• Dificil de leerlos, donde empieza , donde termina
• Dificil de reutilizarlos
• Dificil de probarlos
• Complejos
• Efectos colaterales
• Dificil de ver todo
• Conlleva duplicacion
• Dificil de mantener
• Es propenso a errores
• El código entero debe poder verse en una sola ventana
• El código debe estar a un nivel de abstracción
• Como estuvo tu fin de semana?
• Fui al cine,.. No es necesario mas detalles, que pelicula viste? Ya es
un segundo nivel.
• Eliminar duplicación
• Es dificil de mantener
• Eliminar dependencia
• Revisar el codigo continuamente
Bibliografía
• Refactoring: Improving the Design of Existing Code, Martin
Fowler
• [Link]
%20Refactoring%20-
%20Improving%20the%20Design%20of%20Existing%[Link]
• [Link]
• [Link]