En programación de computadoras y diseño de software , la refactorización de código es el proceso de reestructurar el código fuente existente (cambiando la factorización ) sin cambiar su comportamiento externo. La refactorización tiene como objetivo mejorar el diseño, la estructura y/o la implementación del software (sus atributos no funcionales ), preservando al mismo tiempo su funcionalidad . Las ventajas potenciales de la refactorización pueden incluir una mejor legibilidad del código y una complejidad reducida ; Estos pueden mejorar la capacidad de mantenimiento del código fuente y crear una arquitectura interna o un modelo de objetos más simple, más limpio o más expresivo para mejorar la extensibilidad . Otro objetivo potencial de la refactorización es mejorar el rendimiento; Los ingenieros de software se enfrentan al desafío constante de escribir programas que funcionen más rápido o utilicen menos memoria.
Normalmente, la refactorización aplica una serie de microrrefactorizaciones básicas estandarizadas , cada una de las cuales es (generalmente) un pequeño cambio en el código fuente de un programa de computadora que preserva el comportamiento del software o al menos no modifica su conformidad con los requisitos funcionales. Muchos entornos de desarrollo brindan soporte automatizado para realizar los aspectos mecánicos de estas refactorizaciones básicas. Si se hace bien, la refactorización de código puede ayudar a los desarrolladores de software a descubrir y corregir errores o vulnerabilidades ocultos o inactivos en el sistema al simplificar la lógica subyacente y eliminar niveles innecesarios de complejidad. Si se hace mal, puede no cumplir con el requisito de que no se cambie la funcionalidad externa y, por lo tanto, puede introducir nuevos errores.
Al mejorar continuamente el diseño del código, hacemos que trabajar con él sea cada vez más fácil. Esto contrasta marcadamente con lo que suele suceder: poca refactorización y mucha atención prestada para agregar nuevas funciones de manera oportuna. Si adquiere el hábito higiénico de refactorizar continuamente, descubrirá que es más fácil ampliar y mantener el código.
— Joshua Kerievsky, Refactorización de patrones [1]
La refactorización suele estar motivada al notar un olor a código . [2] Por ejemplo, el método en cuestión puede ser muy largo o puede ser casi un duplicado de otro método cercano. Una vez reconocidos, estos problemas pueden abordarse refactorizando el código fuente o transformándolo en una nueva forma que se comporte igual que antes pero que ya no "huele".
Para una rutina larga, se pueden extraer una o más subrutinas más pequeñas; o para rutinas duplicadas, la duplicación se puede eliminar y reemplazar con una función compartida. No realizar la refactorización puede resultar en la acumulación de deuda técnica ; por otro lado, la refactorización es uno de los principales medios para pagar la deuda técnica. [3]
Hay dos categorías generales de beneficios para la actividad de refactorización.
La ingeniería de rendimiento puede eliminar ineficiencias en los programas, conocidas como exceso de software, que surgen de estrategias tradicionales de desarrollo de software que apuntan a minimizar el tiempo de desarrollo de una aplicación en lugar del tiempo que lleva ejecutarse. La ingeniería de rendimiento también puede adaptar el software al hardware en el que se ejecuta, por ejemplo, para aprovechar procesadores paralelos y unidades vectoriales. [5]
Hay dos momentos posibles para la refactorización.
Un método que equilibra la refactorización preventiva y correctiva es la "responsabilidad compartida de la refactorización". Este enfoque divide la acción de refactorización en dos etapas y dos roles. El desarrollador original del código simplemente prepara el código para la refactorización, y cuando el código huele mal, un desarrollador posterior lleva a cabo la acción de refactorización real. [6]
La refactorización requiere extraer la estructura del sistema de software, los modelos de datos y las dependencias dentro de la aplicación para recuperar el conocimiento de un sistema de software existente. [7] La rotación de equipos implica un conocimiento faltante o inexacto del estado actual de un sistema y sobre las decisiones de diseño tomadas por los desarrolladores salientes. Es posible que otras actividades de refactorización de código requieran un esfuerzo adicional para recuperar este conocimiento. [8] Las actividades de refactorización generan modificaciones arquitectónicas que deterioran la arquitectura estructural de un sistema de software. Este deterioro afecta a propiedades arquitectónicas como la mantenibilidad y la comprensibilidad, lo que puede conducir a un redesarrollo completo de los sistemas de software. [9]
Las actividades de refactorización de código están protegidas con inteligencia de software cuando se utilizan herramientas y técnicas que proporcionan datos sobre algoritmos y secuencias de ejecución de código. [10] Proporcionar un formato comprensible para el estado interno de la estructura del sistema de software, los modelos de datos y las dependencias entre componentes es un elemento crítico para formar una comprensión de alto nivel y luego vistas refinadas de lo que se debe modificar y cómo. [11]
Se deben configurar pruebas unitarias automáticas antes de refactorizar para garantizar que las rutinas sigan comportándose como se espera. [12] Las pruebas unitarias pueden aportar estabilidad incluso a refactorizaciones grandes cuando se realizan con una única confirmación atómica . Una estrategia común para permitir refactorizaciones atómicas y seguras que abarquen múltiples proyectos es almacenar todos los proyectos en un único repositorio , conocido como monorepo . [13]
Con las pruebas unitarias implementadas, la refactorización es entonces un ciclo iterativo en el que se realiza una pequeña transformación del programa , se prueba para garantizar que sea correcto y se realiza otra pequeña transformación. Si en algún momento una prueba falla, el último pequeño cambio se deshace y se repite de otra manera. A través de muchos pequeños pasos, el programa avanza desde donde estaba hasta donde usted desea que esté. Para que este proceso tan iterativo sea práctico, las pruebas deben ejecutarse muy rápidamente, o el programador tendría que dedicar una gran fracción de su tiempo a esperar a que finalicen las pruebas. Los defensores de la programación extrema y otros desarrollos de software ágiles describen esta actividad como una parte integral del ciclo de desarrollo de software .
A continuación se muestran algunos ejemplos de microrefactorizaciones; Es posible que algunos de estos solo se apliquen a ciertos idiomas o tipos de idiomas. Puede encontrar una lista más larga en el libro de refactorización de Martin Fowler [2] [ página necesaria ] y en el sitio web. [14] Muchos entornos de desarrollo brindan soporte automatizado para estas microrefactorizaciones. Por ejemplo, un programador podría hacer clic en el nombre de una variable y luego seleccionar la refactorización "Encapsular campo" desde un menú contextual . Luego, el IDE solicitará detalles adicionales, generalmente con valores predeterminados razonables y una vista previa de los cambios en el código. Después de la confirmación por parte del programador, realizaría los cambios requeridos en todo el código.
Si bien el término refactorización originalmente se refería exclusivamente a la refactorización de código de software, en los últimos años también se ha refactorizado código escrito en lenguajes de descripción de hardware . El término refactorización de hardware se utiliza como término abreviado para refactorización de código en lenguajes de descripción de hardware. Dado que la mayoría de los ingenieros de hardware no consideran que los lenguajes de descripción de hardware sean lenguajes de programación , [20] la refactorización de hardware debe considerarse un campo separado de la refactorización de código tradicional.
Zeng y Huss propusieron la refactorización automatizada de descripciones de hardware analógico (en VHDL-AMS ). [21] En su enfoque, la refactorización preserva el comportamiento simulado de un diseño de hardware. La medida no funcional que mejora es que el código refactorizado puede procesarse mediante herramientas de síntesis estándar, mientras que el código original no. Mike Keating, miembro de Synopsys , también ha investigado la refactorización de lenguajes de descripción de hardware digital, aunque sea manual . [22] [23] Su objetivo es hacer que los sistemas complejos sean más fáciles de entender, lo que aumenta la productividad de los diseñadores.
El primer uso conocido del término "refactorización" en la literatura publicada fue en un artículo de septiembre de 1990 de William Opdyke y Ralph Johnson . [24] Aunque la refactorización de código se ha realizado de manera informal durante décadas, el Ph.D. de 1991 de William Griswold. Esta disertación [25] es uno de los primeros trabajos académicos importantes sobre la refactorización de programas funcionales y procedimentales, seguida por la disertación de William Opdyke de 1992 [26] sobre la refactorización de programas orientados a objetos, [27] aunque toda la teoría y la maquinaria se han desarrollado desde hace mucho tiempo. han estado disponibles como sistemas de transformación de programas . Todos estos recursos proporcionan un catálogo de métodos comunes para la refactorización; Un método de refactorización tiene una descripción de cómo aplicar el método e indicadores de cuándo debe (o no) aplicar el método.
El libro de Martin Fowler Refactoring: Improving the Design of Existing Code es la referencia canónica. [¿ según quién? ]
Los términos "factorizar" y "factorizar" se han utilizado de esta manera en la comunidad Forth desde al menos principios de los años 1980. El capítulo seis del libro de Leo Brodie Thinking Forth (1984) [28] está dedicado al tema.
En programación extrema, la técnica de refactorización del método de extracción tiene esencialmente el mismo significado que factorizar Forth; dividir una "palabra" (o función ) en funciones más pequeñas y más fáciles de mantener.
Las refactorizaciones también se pueden reconstruir [29] post hoc para producir descripciones concisas de cambios de software complejos registrados en repositorios de software como CVS o SVN.
Muchos editores de software e IDE tienen soporte de refactorización automatizada. Aquí hay una lista de algunos de estos editores, o los llamados navegadores de refactorización .
{{cite thesis}}
: CS1 maint: bot: original URL status unknown (link)