Código de refactorización

format_list_bulleted Contenido keyboard_arrow_down
ImprimirCitar
Reestructuración del código informático existente sin cambiar su comportamiento externo

En la programación de computadoras y el diseño de software, la refactorización de código es el proceso de reestructuración del código de computadora existente (cambiando la factorización) sin cambiar su comportamiento externo. La refactorización tiene por objeto mejorar el diseño, la estructura y/o la implementación del software (sus atributos no funcionales), al tiempo que preserva su funcionalidad. Las posibles ventajas de la refactorización pueden incluir una mejor legibilidad del código y una menor complejidad; 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 enfrentan un desafío continuo para escribir programas que funcionen más rápido o usen menos memoria.

Por lo general, la refactorización aplica una serie de microrrefactorizaciones básicas estandarizadas, cada una de las cuales es (normalmente) un pequeño cambio en el código fuente de un programa informático que conserva 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 ocultos o inactivos o vulnerabilidades en el sistema al simplificar la lógica subyacente y eliminar niveles innecesarios de complejidad. Si se hace mal, puede fallar el requisito de que la funcionalidad externa no se cambie y, por lo tanto, puede introducir nuevos errores.

Al mejorar continuamente el diseño del código, hacemos más fácil y fácil trabajar con. Esto contrasta claramente con lo que suele suceder: poco refactoring y mucha atención prestada para añadir de manera conveniente nuevas características. Si te metes en el hábito higiénico de refactorizar continuamente, encontrarás que es más fácil extender y mantener el código.

Joshua Kerievsky, Refactoring to Patterns

Motivación

La refactorización generalmente está motivada por notar un olor en el código. 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 se pueden abordar refactorizando el código fuente o transformándolo en una nueva forma que se comporta 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. Si no se realiza la refactorización, se puede acumular una deuda técnica; por otro lado, la refactorización es uno de los principales medios para pagar la deuda técnica.

Beneficios

Hay dos categorías generales de beneficios para la actividad de refactorización.

  1. Sostenibilidad. Es más fácil corregir errores porque el código fuente es fácil de leer y la intención de su autor es fácil de comprender. Esto podría lograrse reduciendo grandes rutinas monolíticas en un conjunto de métodos concisos, bien conocidos y de uso único. Podría lograrse moviendo un método a una clase más apropiada, o eliminando comentarios engañosos.
  2. Extensibilidad. Es más fácil ampliar las capacidades de la aplicación si utiliza patrones de diseño reconocibles, y proporciona cierta flexibilidad cuando ninguno de ellos haya existido antes.

La ingeniería de rendimiento puede eliminar las ineficiencias en los programas, conocidas como exceso de software, que surgen de las estrategias tradicionales de desarrollo de software que tienen como objetivo minimizar el tiempo de desarrollo de una aplicación en lugar del tiempo que tarda en ejecutarse. La ingeniería de rendimiento también puede adaptar el software al hardware en el que se ejecuta, por ejemplo, para aprovechar los procesadores paralelos y las unidades vectoriales.

Desafíos

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. La rotación de equipos implica un conocimiento inexacto o faltante del estado actual de un sistema y sobre las decisiones de diseño tomadas por los desarrolladores que se van. Otras actividades de refactorización de código pueden requerir un esfuerzo adicional para recuperar este conocimiento. Las actividades de refactorización generan modificaciones arquitectónicas que deterioran la arquitectura estructural de un sistema de software. Dicho deterioro afecta las propiedades arquitectónicas, como la mantenibilidad y la comprensibilidad, lo que puede conducir a un nuevo desarrollo completo de los sistemas de software.

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. 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 refinar las vistas de lo que se debe modificar y cómo.

Pruebas

Se deben configurar pruebas unitarias automáticas antes de la refactorización para garantizar que las rutinas sigan comportándose como se espera. Las pruebas unitarias pueden brindar estabilidad incluso a grandes refactores cuando se realizan con una sola confirmación atómica. Una estrategia común para permitir refactores atómicos y seguros que abarquen múltiples proyectos es almacenar todos los proyectos en un solo repositorio, conocido como monorepo.

Con las pruebas unitarias implementadas, la refactorización es entonces un ciclo iterativo de hacer una pequeña transformación de programa, probarlo para garantizar que sea correcto y hacer otra pequeña transformación. Si en algún momento falla una prueba, el último pequeño cambio se deshace y se repite de una manera diferente. A través de muchos pequeños pasos, el programa se mueve desde donde estaba hasta donde usted quiere que esté. Para que este proceso muy iterativo sea práctico, las pruebas deben ejecutarse muy rápidamente, o el programador tendría que pasar una gran fracción de su tiempo esperando que terminen las pruebas. Los defensores de la programación extrema y otro desarrollo de software ágil describen esta actividad como una parte integral del ciclo de desarrollo de software.

Técnicas

Aquí hay algunos ejemplos de micro-refactorizaciones; algunos de estos pueden aplicarse solo a ciertos idiomas o tipos de idiomas. Se puede encontrar una lista más larga en el libro y el sitio web de refactorización de Martin Fowler. 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 "Encapsular campo" refactorización desde un menú contextual. Luego, el IDE solicitaría detalles adicionales, generalmente con valores predeterminados sensibles 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.

  • Técnicas que permiten una mayor comprensión
    • Programa Dependence Graph - representación explícita de las dependencias de datos y control
    • Sistema de dependencia Gráfico - representación de llamadas de procedimiento entre PDG
    • Inteligencia de software - ingeniería inversa el estado inicial para entender las dependencias existentes de aplicación
  • Técnicas que permiten más abstracción
    • Campo encapsulado – código de fuerza para acceder al campo con métodos de filtración y depuración
    • Generalizar el tipo – crear tipos más generales para permitir más compartir código
    • Sustitúyase el código de comprobación de tipo con estado/estrategia
    • Reemplazar condicional con polimorfismo
  • Técnicas para dividir el código en piezas más lógicas
    • La componenteización descompone el código en unidades semánticas reutilizables que presentan interfaces claras, bien definidas y sencillas de uso.
    • Extract class mueve parte del código de una clase existente a una nueva clase.
    • Extract method, to turn part of a larger method into a new method. Derribando el código en piezas más pequeñas, es más fácil de entender. Esto también es aplicable a las funciones.
  • Técnicas para mejorar los nombres y la ubicación del código
    • Mover método o mover campo – pasar a una clase más apropiada o archivo fuente
    • Renombrar método o renombrar campo – cambiar el nombre en un nuevo que mejor revela su propósito
    • Retirar – en programación orientada hacia objetos (OOP), pasar a una superclase
    • Bajar – en OOP, pasar a una subclase
  • Detección automática de clones

Refactorización de hardware

Si bien el término refactorización originalmente se refería exclusivamente a la refactorización del código de software, en los últimos años también se ha refactorizado el código escrito en lenguajes de descripción de hardware. El término refactorización de hardware se utiliza como término abreviado para la 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, la refactorización de hardware debe considerarse un campo separado de la refactorización de código tradicional.

Zeng y Huss han propuesto la refactorización automatizada de descripciones de hardware analógico (en VHDL-AMS). En su enfoque, la refactorización conserva el comportamiento simulado de un diseño de hardware. La medida no funcional que mejora es que el código refactorizado puede procesarse con herramientas de síntesis estándar, mientras que el código original no. Mike Keating, compañero de Synopsys, también ha investigado la refactorización de lenguajes de descripción de hardware digital, aunque sea una refactorización manual. Su objetivo es hacer que los sistemas complejos sean más fáciles de entender, lo que aumenta las posibilidades de los diseñadores. productividad.

Historia

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. El doctorado de Griswold tesis, El doctorado de Opdyke tesis, publicada en 1992, también utilizó este término. Aunque la refactorización del código se ha realizado de manera informal durante décadas, el doctorado de 1991 de William Griswold. La disertación 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 sobre la refactorización de programas orientados a objetos, aunque toda la teoría y la maquinaria han estado disponibles durante mucho tiempo 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 debe) aplicar el método.

El libro Refactoring: Improving the Design of Existing Code de Martin Fowler es la referencia canónica.

Los términos "factoring" y "factorizar" se han utilizado de esta manera en la comunidad de Forth desde al menos principios de la década de 1980. El capítulo seis del libro de Leo Brodie Thinking Forth (1984) está dedicado al tema.

En la programación extrema, la técnica de refactorización del método de extracción tiene esencialmente el mismo significado que la factorización en Forth; para 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 a posteriori para producir descripciones concisas de cambios de software complejos registrados en repositorios de software como CVS o SVN.

Refactorización de código automatizada

Muchos editores de software e IDE cuentan con soporte de refactorización automatizado. Es posible refactorizar el código de la aplicación así como el código de prueba. Aquí hay una lista de algunos de estos editores, o los llamados navegadores de refactorización.

  • DMS Software Reengineering Toolkit (Implementos de refactorización a gran escala para C, C++, C#, COBOL, Java, PHP y otros idiomas)
  • Eclipse based:
    • Eclipse (para Java, y en menor medida, C++, PHP, Ruby y JavaScript)
    • PyDev (para Python)
    • Photran (un plugin de Fortran para el Eclipse IDE)
  • Embarcadero Delphi
  • IntelliJ basado:
    • Resharper (para C#)
    • AppCode (para Objetivo-C, C y C++)
    • IntelliJ IDEA (para Java)
    • PyCharm (para Python)
    • WebStorm (para JavaScript)
    • PhpStorm (para PHP)
    • Android Studio (para Java y C++)
  • JDeveloper (para Java)
  • NetBeans (para Java)
  • Smalltalk: La mayoría de los dialectos incluyen poderosas herramientas de refactorización. Muchos usan el navegador original de refactorización producido a principios de los 90 por Ralph Johnson.
  • Visual Studio basado:
    • Visual Studio (para.NET y C++)
    • CodeRush (addon for Visual Studio)
    • Asistencia Visual (addon para Visual Studio con soporte refactoring para C# y C++)
  • Wing IDE (para Python)
  • Xcode (para C, Objective-C y Swift)
  • Qt Creator (para C++, Objective-C y QML)

Contenido relacionado

Ganancia neta (telecomunicaciones)

Verdadero BÁSICO

Principio del beso

Más resultados...
Tamaño del texto:
Copiar