Sé que la refactorización es "cambiar la estructura de un programa para que la funcionalidad no cambie". Estaba hablando con algunos de los chicos con los que estoy trabajando en mi proyecto de último año en la universidad y me sorprendió que tuvieran una visión mucho más amplia (a falta de una palabra mejor) de la refactorización.
Considero que la refactorización son cosas como extraer métodos y cambiar el nombre de las clases. También sugirieron cosas como cambiar las estructuras de datos (como un Java LinkedList
a un ArrayList
), cambiar algoritmos (usar la clasificación por fusión en lugar de la clasificación por burbujas) e incluso reescribir grandes trozos de código como refactorización.
Estaba bastante seguro de que estaban equivocados, pero no pude dar una buena razón porque lo que estaban sugiriendo cambió el programa (y presumiblemente lo mejoró) sin cambiar su comportamiento. ¿Tengo razón y, lo que es más importante, por qué?
fuente
Fowler traza una línea clara entre los cambios en el código que afectan su comportamiento y los que no. A los que no lo hacen, los llama "refactorización". Ésta es una distinción importante, porque si dividimos nuestro trabajo en actividades de modificación de código de refactorización y no refactorización (Fowler lo llama "usar sombreros diferentes"), podemos aplicar técnicas diferentes y apropiadas para el objetivo.
Si estamos haciendo una refactorización o una modificación de código para preservar el comportamiento:
Si estamos haciendo una modificación de código que cambia el comportamiento:
Si perdemos de vista esta distinción, entonces nuestras expectativas para cualquier tarea de modificación de código dada son confusas y complejas, o al menos más confusas y más complejas que si la tuviéramos en cuenta. Por eso la palabra y su significado son importantes.
fuente
Para dar mi vista:
Pequeños cambios incrementales que dejan el código en un mejor estado del que se encontró
Definitivamente si: cambios "cosméticos" que no están directamente relacionados con las funciones (es decir, no se pueden facturar como una solicitud de cambio).
Definitivamente no: reescribir partes grandes claramente viola la parte "pequeña, incremental". La refactorización se usa a menudo como lo opuesto a una reescritura: en lugar de hacerlo de nuevo, mejora lo existente.
Definitivamente Quizás: Reemplazar estructuras de datos y algoritmos es algo así como un caso límite. La diferencia decisiva aquí, en mi opinión, son los pequeños pasos: esté listo para entregar, esté listo para trabajar en otro caso.
Ejemplo: Imagine que tiene un módulo de aleatorización de informes que se ralentiza por el uso de un vector. Ha perfilado que las inserciones vectoriales son el cuello de botella, pero desafortunadamente el módulo se basa en la memoria contigous en muchos lugares, por lo que al usar una lista, las cosas se rompen silenciosamente.
Reescribir significaría deshacerse del Módulo y construir uno mejor y más rápido desde cero, simplemente recogiendo algunas piezas del anterior. O escribiendo un nuevo núcleo y luego ajustándolo al diálogo existente.
Refactorizar significaría tomar pequeños pasos para eliminar la aritmética del puntero, de modo que el cambio. Tal vez incluso cree una función de utilidad que envuelva la aritmética del puntero, reemplazando la manipulación directa del puntero con llamadas a esa función, luego cambie a un iterador para que el compilador se queje de lugares donde todavía se usa la aritmética del puntero, luego cambie a ay
list
luego elimine el función de ultilidad.La idea detrás es que el código empeora por sí solo. Al corregir errores y agregar funciones, la calidad decae en pequeños pasos: el significado de una variable cambia sutilmente, una función obtiene un parámetro adicional que rompe el aislamiento, un bucle se vuelve un poco complejo, etc. Ninguno de estos es un error real, puede No dice un recuento de líneas que hace que el ciclo sea complejo, pero perjudica la legibilidad y el mantenimiento.
Del mismo modo, cambiar el nombre de una variable o extraer una función no son mejoras tangibles en sí mismas. Pero todos juntos, luchan contra la lenta erosión.
Como un muro de guijarros donde todos los días uno cae al suelo. Y todos los días, un transeúnte lo recoge y lo devuelve.
fuente
Con la definición de Martin Fowler en mente,
... Creo que claramente tienes razón.
Cambiar un algoritmo a algo mucho más rápido obviamente no es refactorizar, ¡porque se cambia el comportamiento externo! (Por otra parte, si el efecto nunca se nota, tal vez podría llamarlo refactorización después de todo, y también optimización prematura. :-)
Esta es una manía mía; es molesto cuando la gente usa el término de manera descuidada; incluso me he encontrado con algunos que podrían usar la refactorización para básicamente cualquier tipo de cambio o corrección. Sí, es una palabra de moda moderna y genial y todo eso, pero no hay nada de malo en términos simples y antiguos como cambio , reescritura o mejora del rendimiento . Deberíamos usarlos cuando sea apropiado, y reservar la refactorización para los casos en los que realmente esté mejorando la estructura interna de su software. Dentro de un equipo de desarrollo, especialmente, es importante tener un lenguaje común para discutir con precisión su trabajo.
fuente
Si cambia la interfaz de un fragmento de código, lo considero más que una refactorización.
El caso típico de refactorización es
Esto significa que el término refactorización es relativo a la interfaz que está discutiendo. es decir, podría estar refactorizando el código detrás de una interfaz, mientras cambia más extensamente el código de otra en un nivel inferior (¿tal vez esa distinción es lo que genera la confusión entre usted y sus colegas aquí?)
fuente
Creo que tienes razón, pero discutir sobre el significado de una palabra no es particularmente interesante ni productivo.
fuente
http://en.wikipedia.org/wiki/Code_refactoring
Estoy de acuerdo en que la refactorización del código incluye romper el código existente. Solo asegúrese de tener pruebas unitarias para que no introduzca ningún error y el resto del código se compile. El uso de herramientas de refactorización como Resharper para C # hace que esto sea muy fácil.
fuente
Yo discrepo :
Ya conoce los términos más precisos que se utilizan para los subconjuntos de refactorización, y sí, es un término muy general.
fuente
Creo que nadie puede beneficiarse de una definición demasiado fuerte del término 'refactorización'. El límite entre cómo lo percibes y tus colegas es borroso y puede estar más cerca de su punto de vista o el tuyo dependiendo de muchos hechos. Dado que es dinámico, intentemos definirlo. En primer lugar, defina los límites del sistema o subsistema que está intentando refactorizar.
Si se trata de un método, mantenga fijo el nombre, los argumentos de entrada, el tipo de valor devuelto y posiblemente las declaraciones de lanzamiento. Aplique todos los cambios dentro del método sin cambiar la forma en que se ve fuera.
Si refactoriza una clase, corrija su API pública y use el cambio de nombre de las variables, los métodos de extracción y todas las demás técnicas disponibles cambian la clase para que sea más legible y / o más eficaz.
Si la parte del código que está refactorizando es un paquete o un módulo, haga la refactorización dentro de él, posiblemente cambiando el nombre de las clases, eliminando, introduciendo interfaces, empujando / tirando de código en super / subclases.
fuente
Refactorización = mejorar los requisitos no funcionales manteniendo inalterados los funcionales.
Requisitos no funcionales = modularidad, capacidad de prueba, facilidad de mantenimiento, legibilidad, separación de preocupaciones, principios de Liskov, etc.
fuente