Retos en la Adopción del Refactoring - Junta General del MexALN 28/06/2012
1. Retos en la Adopción
de la Práctica del
Refactoring
Alfredo Chávez Vázquez
2. Vámonos por partes:
Empecemos por el principio
Refactoring y el ciclo de vida del software
Razones para refactorizar: code smells.
¿Hacia dónde dirigirse?
¿Porqué Pépe no refactoriza?
Bibliografía
4. Empecemos por el principio
¿Qué es el refactoring?
Lo el refactoring NO es
Terminología:
¿Verbo o sustantivo?
¿“refactorizar” o “refactorar”?
Los principios
¿Cuándo hacer refactoring?
5. ¿Qué es el Refactoring?
Definición:
Un cambio hecho a la estructura interna del
software para hacerlo más fácil de entender y
más barato de modificar, sin modificar su
comportamiento observable.
--Martin Fowler
6. Lo el refactoring NO es
Optimización de código.
“Limpieza” de código.
Reescritura o reconstrucción.
Reducir el volumen de código (aunque a
veces sucede)
7. Terminología
Sustantivo:
Cada una de las modificaciones hechas al
código fuente que cumplen con la definición.
Verbo:
Elacto de aplicar uno o varios refactorings al
código fuente.
8. Terminología (cont.)
Re-factorizar:
Implica una asociación con el concepto de
“factorizar”: Descomponer un polinomio en el
producto de otros de menor grado.
Re-factorar:
Implica una asociación con “factura”: Acción y
efecto de hacer.
9. Los principios del refactoring
La prioridad es mantener el
comportamiento actual.
Comenzar con un objetivo en mente.
Siempre proceder en pasos pequeños y
controlados (baby steps)
Nunca refactorizar y arreglar/agregar/
modificar el código al mismo tiempo (las
“dos cachuchas”)
10. ¿Cuándo refactorizar?
La regla de tres de Don Roberts:
1. La primera vez que hagas algo, solo hazlo.
2. La segunda vez que hagas algo similar,
“sóbate” por duplicar, pero sigue adelante.
3. La tercera vez que encuentres algo
similar:
¡Strike 3!
¡Refactoriza!
11. El refactoring y el ciclo de vida
De sencillo… a complicado… a monstruo!
12. Refactoring y el ciclo de vida del
software
Mito: “un proyecto de software bien administrado lleva a cabo un
desarrollo metódico de requerimientos y define una lista estable de
las responsabilidades del programa. El diseño sigue los
requerimientos, y se hace con cuidado para que la codificación
pueda proceder de forma lineal, de principio a fin,
lo que implica que la mayor parte del código se
puede escribir, probar y olvidar de una sola vez...”
Todo software exitoso cambia.
Fred P. Brooks Jr.
13. El problema de fondo
La “evolución” del software tiende a ser tomada
como un “mal necesario”.
Nunca es posible saber tanto al comienzo del
desarrollo como se llega a saber después.
El objetivo en la mente de la mayoría de los
desarrolladores es “haz que funcione”.
La mayoría de los desarrolladores no ven
fácilmente su propio código con ojo crítico.
14. … o desde otro punto de vista
Prisa
Apatía
Ignorancia
Ambición
Flojera
Orgullo
15. La regla cardinal de la evolución
de software
La evolución siempre debe conducir a una
mejora en la estructura interna del software.
--Steve McConnel
No hay software tan grande, enredado o
complejo que el mantenimiento no pueda
empeorarlo
--Gerald Weinberg
16. El argumento económico
Entre 60% y 80% del costo total de un
proyecto de software ocurre después de
que la primera versión es liberada.
El software difícil de leer es difícil de
modificar.
El software que incluye lógica condicional
compleja es difícil de modificar.
El software que tiene lógica duplicada es
difícil de modificar.
El software que requiere funcionalidad
adicional que requiere modificar el código
de producción es difícil de extender.
Por lo tanto, el impacto de la calidad del
código fuente sobre el costo/beneficio de Fuente: “Frequently Forgotten Fundamental
un proyecto es directo y a largo plazo. Facts about Software Engineering”
--Robert L. Glass
17. Razones para refactorizar:
“Code Smells”
Los que engordan
Los redundantes
Los que paralizan
Los que acoplan
Los desorientados (a
objetos)
Comentarios
18. Los que engordan
Métodos/funciones largos.
Extraer método, remplazar temporal
por query, etc.
Clases/módulos largos.
Extraer superclase, extraer
clase, remplazar valor por objeto
Listas largas de parámetros.
Introducir parámetro-objeto, remplazar
parámetro por método
Obsesión primitiva.
Remplazar arreglo por objeto
, remplazar valor por objeto
Racimos de datos.
Extraer clase, preservar objeto.
20. Los que paralizan
Cambio/evolución divergente.
Extraer método, extraer clase.
Cirugía con escopeta.
Mover método, mover campo…
Jerarquías de herencia
paralelas.
Mover método, mover campo.
21. Los que acoplan
Envidia de características.
Mover método, extraer método…
Intimidad inapropiada.
Mover método, cambiar herencia por
delegación…
Cadenas de mensajes.
Ocultar delegado
El intermediario.
Eliminar
intermediario, insertar
método…
22. Los desorientados (a objetos)
Sentencias “switch”.
Remplazar condición con
polimorfismo, remplazar parámetro
con métodos…
Atributos temporales.
Extraer clase, introducir objeto-nulo…
Legado indeseable.
Remplazar herencia por delegación.
Clases alternativas con interfaces
incompatibles.
Renombrar método, mover método.
23. Comentarios
¿¡¿¡QUEEEEEEEEEÉ!?!?
También incluyen #regiones en .NET
Extraer método, renombrar método,
introducir aseveración, introducir objeto-
método…
24. ¿Hacia dónde dirigirse?
“Tal parece que la perfección se alcanza, no
cuando no hay nada que añadir, sino
cuando no queda nada que quitar”
-- Antoine de Saint Exupéry
25. Reglas del diseño simple
1. Pasa todas las pruebas (p.e. cumple los
requerimientos).
2. No contiene duplicación.
3. Expresa claramente la intensión del
programador.
4. Minimiza el número de clases y métodos
para expresar dicha intención.
26. ¿Porqué Pepe no refactoriza?
El mito del management.
Bases de datos
Ver “Refactoring Databases” de Scott Ambler.
La “propiedad privada” del código.
Interfaces “publicadas”.
Desconocimiento.
Miedo.
27. El mito del management
El management no requiere ¡Hey tú! Solo acabalo,
¿quieres? Te pago por
que justifiquemos cada “for” programar, no limpiar.
que escribimos.
El refactoring debe ser una
tarea continua, no discreta.
Refactorizar un poco, todo
el tiempo.
code → code → code → clean = code → code → code→¡OUCH!
28. Bases de datos
La base de datos ES la
arquitectura.
El código de negocio está
fuertemente acoplado al
esquema.
La migración de datos es
ardua y compleja
29. Propiedad privada del código
Cada módulo le “pertenece” a un
desarrollador.
Todo el trabajo se detiene si el “dueño” no
está disponible.
Nadie quiere “adoptar” al código sin
“dueño”.
30. Interfaces “publicadas”
Distinción entre “público” y “publicado”
No se puede saber quiénes y cuantos son
los usuarios del código.
Alternativas:
Versionamiento de interfases.
31. Desconocimiento y miedo
“Si no está roto, no lo arregles”.
Desconocimiento de la técnica de
refactoring.
Desconocimiento de las herramientas
disponibles.
Desconocimiento del código mismo.
Falta de conocimiento y experiencia en
diseño.
32. Bibliografía
“Refactoring: Improving the design of existing code” de Martin
Fowler.
“Code Complete, Second Edition” de Steve McConnell.
“Refactoring Object-Oriented Frameworks”, tesis de
doctorado de William F. Opdyke.
“Smalltalk Best Practice Patterns” de Kent Beck.
“Refactoring to Patterns” de Joshua Kerievski.
“AntiPatterns: Refactoring Software, Architectures, and
Projects in Crisis” de William J. Brown et al.