REDcientifica

Refactorización de código
Manuel de la Herrán Gascón
Universidad de Deusto
Informática, Inteligencia Artificial, Sistemas Complejos, Programación

Artículo publicado en M2C-Consulting en Septiembre de 2011.
www.m2c.es


En el desarrollo de proyectos informáticos es habitual encontrar situaciones en las que un cambio aparentemente simple conlleva un gran coste de implementación. Y al contrario: en ocasiones es posible dotar al sistema de una nueva y gran funcionalidad con un esfuerzo muy pequeño.


¿Quieres saber más?
Regístrate para leer más artículos como este

¿Por qué ocurre esto? ¿Bajo que condiciones se da una u otra situación? ¿Que necesitamos para que en nuestro sistema sea posible añadir nuevas funcionalidades con un coste mínimo? La respuesta a estas preguntas está relacionada con una actividad omnipresente pero de nombre poco conocido: La refactorización del código.

Refactorizar consiste en modificar y re-escribir código informático de manera que siga realizando la misma función externa, pero con algún tipo de ventaja en cuanto a su estructura interna. Los posibles objetivos de la refactorización son muchos: obtener un código más reutilizable, más fácil de entender, más compacto, o más eficiente. Estos objetivos están relacionados con la calidad del código (cómo lo hace) y no con su funcionalidad (qué hace).

Todos los programadores refactorizan código, aunque la mayoría de ellos desconoce el término. Dejando a un lado la forma en la que llamamos a las cosas, lo importante es ser conscientes de la necesidad de adaptar el código para facilitar su evolución y la incorporación de nuevas funcionalidades. Y por tanto, añadir esta tarea en los planes.

Llegado el momento de incluir la tarea en el plan, el término tiene su cierta utilidad: "refactorización" puede ser mucho más glamuroso que un ambiguo "mejorar el código". En cualquier caso, es mejor hablar de adaptar el código (para permitir la incorporación de nueva funcionalidad), más que de mejorarlo.



¿Por que? Porque si hablamos de "mejorar" podemos dar a entender que aquello no estaba bien antes, sin ser ésto cierto. La estructura óptima de un fragmento de código depende de su funcionalidad externa y de su contexto. Cuando la funcionalidad se amplía o el contexto cambia, es lógico que la estructura interna también evolucione.

Por ejemplo, añadir tres nuevos parámetros de entrada y duplicar el tamaño de una función, cambiando todas las llamadas a esa función en el resto del código, sólo tiene sentido si los nuevos parámetros van a ser realmente utilizados. Es natural que a medida que los requisitos evolucionan, también lo haga el código que ya estaba funcionando. El código era óptimo antes, sin los tres parámetros, y lo es ahora, con los nuevos parámetros. El código no ha mejorado, simplemente lo estamos "adaptando" o "evolucionando", es decir, estamos "refactorizando".

¿Cuándo refactorizar?

Existen enfoques metodológicos que ponen gran énfasis en la refactorización. Según algunos autores, debemos refactorizar siempre, en cada oportunidad, sin descanso. En general, podemos decir que es un enfoque adecuado. ¿Por qué? Veámoslo desde una cierta perspectiva:

Al igual que en tantas otras actividades, en el desarrollo de software se busca un equilibrio entre dos extremos opuestos. Por una parte queremos dotar al sistema de nueva funcionalidad lo antes posible. Por otra parte, deseamos facilitar el mantenimiento del código existente, así como la incorporación de nueva funcionalidad en el futuro.

Pensemos en algunos casos extremos. En uno de ellos, imaginemos un grupo de programadores desarrollando aplicaciones de entretenimiento. El equipo trabaja bajo la siguiente premisa: cada semana se debe generar un juego diferente, que sólo estará activo durante ese tiempo. Una vez finalizado el periodo, el juego deja de estar disponible para los usuarios.

En el otro extremo, pensemos en el desarrollo de un sistema gestor de contenidos (CMS: Content Management System) para varias publicaciones. Se espera que el CMS esté activo durante al menos 10 años, y no se ponen límites a su alcance: La intención es incluir continuamente nuevas funcionalidades en el sistema: nuevos formatos, plantillas, canales, publicaciónes, interacción con el usuario etc.

Seguramente, ambos equipos "reutilizarán" código, pero lo harán de forma totalmente diferente. Mientras que el primer equipo dispondrá de gran cantidad de código "muerto" que servirá como ejemplo para copiar y pegar en los nuevos desarrollos, casi todo el código que genere el segundo equipo se deberá mantener "vivo" y en perfectas condiciones a medida que se incorporen nuevas funcionalidades al sistema.

El el primer caso, los tiempos de desarrollo serán más predecibles, y dependerán de la complejidad de los nuevos juegos, y de lo mucho o poco que se parezcan a los juegos anteriores. En el segundo caso en cambio, si sólo conocemos el nuevo comportamiento externo deseado para la aplicación CMS, será muy difícil estimar el coste que supondrá añadir esa nueva funcionalidad: el coste dependerá totalmente de la forma en la que se haya desarrollado el sistema. Especialmente, dependerá de si el código es reutilizable, compacto y fácil de entender: Dependerá de si se ha refactorizado suficientemente.

Este segundo caso es mucho más común que el primero, y en general, cuanto mayor es un proyecto, mayores necesidades de refactorización conlleva. De hecho la necesidad de refactorización es directamente proporcional a la complejidad y a la necesidad de mantenimiento, e inversamente proporcional a la calidad del código, en el sentido de su adecuación a las condiciones actuales.

Podríamos representarlo con una fórmula. En una primera aproximación, podemos hacer equivalentes complejidad y tamaño. Por otra parte, la "necesidad de mantenimiento" está relacionada con el tiempo que se espera que el sistema se encuentre activo, y con el número de cambios esperados en ese tiempo. Entonces tenemos que:

[Necesidad de Refactorización] = [Tamaño del sistema] * [Esperanza de vida del sistema] * [Número de cambios previstos] / [Calidad actual]

Seguramente el "peso" de los factores sobre el resultado sea diferente al aquí representado, especialmente porque es más correcto decir que la complejidad crece exponencialmente con el tamaño. Además, no se trata tanto del número de cambios previstos, como de su complejidad. Por tanto una segunda aproximación puede ser de esta forma:

[Necesidad de Refactorización] = [Complejidad actual] * [Complejidad futura] * [Esperanza de vida del sistema] / [Calidad actual]

O mejor así:

[Necesidad de Refactorización] = K1 ^ [Tamaño actual] * K2 ^ [Tamaño de los cambios] * [Esperanza de vida del sistema] / [Calidad actual]

Queda pendiente, y fuera de la ambición de este artículo, establecer experimentalmente medidas para estas variables y ajustar la fórmula adecuadamente.

En cualquier caso, es evidente que es un duro trabajo tener bajo control la complejidad creciente de un sistema de cierto tamaño, que evoluciona y que pretende mantenerse vivo durante un largo tiempo. Gran parte de este esfuerzo consiste en la refactorización.

Pero la "dureza" de esta tarea no se debe a su propia complejidad (de hecho, refactorizar es una de las tareas más simples y mecánicas para un programador). La "dureza" de la tarea es debida a que habitualmente se infravalora su importancia. Desafortunadamente, la refactorización tiene difícil "visibilidad" en el proyecto, ya que por definición, no afecta al comportamiento del sistema, y sus beneficios no son obvios para quienes no están familiarizados con su estructura interna.

Sin embargo es fundamental para mantener al sistema vivo. Los buenos programadores lo saben y es por ello que refactorizan "siempre, en cada oportunidad, sin descanso", y si hace falta, "a escondidas" del plan. Salvo en las contadas excepciones en las que el resultado de la fórmula anterior se aproxima a cero (sistemas pequeños, efímeros o apenas sin cambios), en todos los demás casos, la refactorización es necesaria e imprescindible.

La refactorización, metáfora del sueño

Existe un curioso paralelismo entre la refactorización en los sistemas artificiales, y los procesos relacionados con el dormir y el soñar en los seres vivos. El hecho de dormir y soñar no parece representar una ventaja obvia, a no ser que sea necesaria una suerte de proceso de "reorganización" mental, no sólo de la información recibida, sino también de los mecanismos para procesarla, para poder seguir aplicando los procesos cognitivos con éxito. Eso parece ocurrir tanto en unos como en otros sistemas complejos.

Tanto los seres vivos como las máquinas inteligentes, sueñan (o refactorizan).

Enlaces:

Agilizar.es - Juan Gutiérrez
http://agilizar.es/blog/category/refactorizacion/

Refactoring - Martin Fowler
http://refactoring.com/

Refactorización en Código Fortran Heredado - Mariano Méndez et al.
http://jeff.over.bz/papers/2010/cacic2010.pdf




 ¿Te ha gustado este artículo?
Colabora con
REDcientifica
desde 1 euro


  



Comentarios

2011-10-09 23:08:59
exelente , gracias.





2011-11-15 15:33:29
Muy buen artículo. Lo compartiré.



Les animo también a que den soporte a feeds (rss/atom) y Google+1. Así es más fácil seguirlo y promocionarlo.





2011-11-15 16:52:54
Gracias. He añadido un párrafo final que quedó en el tintero.

"La refactorización, metáfora del sueño". Espero que les guste.



Manuel.



2011-11-15 17:44:07
Gracias por la sugerencia Google+ y RSS. ¿Podría enviarnos por este medio o por otro su usuario de Google+ para ponernos en contacto? Gracias.



Admin.





2011-11-16 12:11:36
Claro, mi perfil en google es

https://plus.google.com/104718757519673756328/about



(soy el que escribió el 2011-11-15 16:52:54)



   

Enviar un comentario anónimo
Los comentarios se publican por defecto de forma anónima, pero si quieres, puedes indicar tu nombre o nick en el propio comentario. No se permiten caracteres html. Para añadir un link, pon la URL en una línea independiente y la convertiremos en un enlace.

¿Eres humano? 



REDcientifica

Ciencia, Tecnología y Pensamiento

¿Has olvidado tu contraseña?
Nick o Email
Password

Conectados
recientemente


admin  manu  sergio  tefi  the_lone_dreamer  
euteronomio  mejoratotal  ricardo  sinvoltearatras  alejandro  
juan_chamero  historicas  maestro0326  alberto1  k_ookami  
castfela  derechosparalosanimales  dani  preguntas  vicent  
 
Últimos comentarios
» ¿Como puede ser posible ser objetivo? Se puede ser menos subjetivo, pero no dejar de ser subjetiv...
» Hola tengo una duda con respecto a la observación pedagógica y los filtros interpretativos... ell...
» Trato de averiguar si soy humano. Este asunto del Observador , duplica mi estado de ansiedad. Par...
» Me gustaria donar el euro,pero no me gustan las tarjetas por internet.
» si, muy utiles los libros. por lo demas, la ilusion del mas alla, es algo a superar. y en los lib...
» Que no se pierda el hábito de la lectura. Al leer se practican, agilizan y desarrollan todos los ...
» si, ya ha sido corregido. por cierto habeis probado el editor de robots? estamos experimentando c...
» Gracias por detectar mi error. Espero que el Administrador lo corrija.
» Es un tema muy complejo y en el que todavía estamos muy 'empapados' como para tener en claro qué ...
» me parece una brutalidad, una salvajada, un absurdo, una locura
» Si, parece una errata. Corregido. Admin.
» LA REALIDAD UNIVERSAL ES COMO ES. LOS HUMANOS CON NUESTROS LIMITADOS SENTIDOS SOLO LA PERCIBIMOS ...
» FAVOR DE CORREGIR, LAS NEURONAS TIENEN UN AXÓN Y VARIAS DENDRITAS, (NO DENTRITAS)...POR LO DEMÁS,...
» Cada vez las relaciones humanas son mejores.


Subjects

 redcientifica.org en Twitterredcientifica.org en Facebookredcientifica.org en Google+ 

redcientifica.org en LinkedIn




Sobre nosotros
Misión de REDcientífica
Condiciones de publicación
Entrevista
Contacto
RIMI: Red de Investigación Materno-Infantil
Enlaces
Okté
Mejora Total
aIRcenter.net
XARXA cientifica
Bosque de letras
La mejor compra
Más que cuentos
idomain.info
Total Improvement
SCI pool
Human Evol
Project Finance Network
Relaciones con clientes
Libros raros
Redacción Eficaz
Portal de Empleo
urlpuzzle
Europa Libre
Madrid Metal
Modelos de Negocio en Internet
Financiación de proyectos
Computación Evolutiva
pxch
gooko
mejorgratis.org




Sites using
phpMySocial

Red Científica
RIMI
EnterValue
Europa Libre
FAQking
Financiación de proyectos
Gestión del cambio
Gestión Total
Gooko
GuayaKill
Health and Intenet
Hipótesis
Humana
Ingresos Pasivos
Internet y Medicina
La voz del cliente
limite.org
Madrid Metal
Mejor Gratis
Metal Guate
Modelos de negocio
netarbe
Optimización de Procesos
Pinche Metal
Puro Metal
pxch
Quito Metal
Red Avanza
REDgaia
Red Humana
Red Técnica
Relaciones con Clientes
Salud y Tecnología
texf
JosuKa
Europa Libre
Internet and Medicine
Internet y Salud
MadridMini
Punto net
Wiawiw