refactoring - software - ¿Cuándo no debes refactorizar?
refactorizar js (16)
¿La necesidad de refactorizar el código se basa en gran medida en la propensión de las personas a cortar y pegar el código en lugar de pensar en la solución y hacer la factorización de antemano? En otras palabras, siempre que sienta la necesidad de cortar y pegar un código, simplemente haga de esa parte de código una función y documéntela.
He tenido que mantener demasiado código donde a las personas les resultaba más fácil cortar y pegar una función completa, solo para realizar uno o dos cambios triviales, que podrían haberse parametrizado fácilmente. Pero al igual que la experiencia de muchos otros, tratar de refactorizar parte de este código hubiera tomado MUCHO tiempo y hubiera sido muy arriesgado.
Tengo 4 proyectos en los que una colección de funciones de la línea 10K simplemente se copió y modificó según fue necesario. Esta es una horrible pesadilla de mantenimiento. Especialmente cuando el código tiene MUCHOS problemas, por ejemplo, suposiciones endianqueadas, toneladas de variables globales, etc. Me siento bilis en la garganta con solo pensarlo.
Todos sabemos que la refactorización es buena y me encanta tanto como el siguiente tipo, pero ¿tiene casos reales en los que es mejor no refactorizar?
¿Algo así como el tiempo crítico o la sincronización? Razones técnicas o humanas son igualmente bienvenidas. Casos reales de escenarios y experiencias un plus.
Edit : de las respuestas hasta ahora, parece que la única razón para no refactorizar es el dinero. Mi pregunta es mayormente relativa a algo como esto: suponga que le gustaría realizar el "método de extracción", pero si agrega la llamada a la función adicional, hará que el código sea un poco menos rápido y dificultará una sincronización muy estricta. Solo para darte una idea de lo que quiero decir.
Otra razón por la que a veces escuché es que "los cambios en el diseño del código actual se sentirán molestos por los cambios". Por supuesto, dudo que esta sea una buena razón.
Aquí está mi experiencia:
No refactorizar
- Cuando no tenga un paquete de pruebas que acompañe el código que desea refactorizar. Es posible que desee desarrollar el traje de prueba primero en su lugar.
- Cuando su gerente no se preocupa realmente por el mantenimiento y la extensibilidad de la base de código actual , en lugar de eso, se preocupa mucho por poder entregar el producto a tiempo, especialmente para el proyecto con un calendario breve y ajustado.
Como escribe Martin Fowler, no debe refactorizar si se acerca una fecha límite. Ese tiempo en el proyecto es más adecuado para eliminar errores en lugar de mejorar el diseño (refactorización). Haga la refactorización omitida esta vez directamente después de que finalice el plazo.
Cuando no es rentable. Hay un tipo en el lugar donde trabajo, a quien le encanta refactorizar. Hacer el código perfecto lo hace muy feliz. Puede revisar un árbol de proyecto actual e ir a la ciudad en él, mover funciones y clases y ajustar las cosas para que se vean geniales, tengan mejor flujo y sean más extensibles en el futuro.
Lamentablemente, no vale la pena el dinero. Si pasa una semana refactorizando algunas clases en unidades más funcionales con las que podría ser más fácil trabajar en el futuro, ese es el salario de una semana perdido para la compañía sin mejoras notables en el balance final.
El código nunca será absolutamente perfecto. Aprendes a vivir con eso y mantienes las manos fuera de algo que podría hacerse mejor, pero tal vez no valga la pena.
Cuando realmente no sabes lo que el código está haciendo en primer lugar. Y sí, he visto a gente ignorar esa regla.
Cuando tienes otras cosas para construir. Siempre tengo ganas de refactorizar un sistema existente cuando se supone que estoy haciendo otra cosa.
Es solo una compensación de costo-beneficio. Calcule el costo de refactorizar, calcule los beneficios, determine si realmente tiene tiempo para refactorizar otras tareas, determine si la refactorización es la mejor compensación de tiempo-beneficio. Puede haber otras tareas más dignas de hacer.
Hmmm - No estoy de acuerdo con lo anterior (primera respuesta). Dado el código sin pruebas, puede refactorizarlo para hacerlo más comprobable.
No refactoriza el código cuando no puede probar el código resultante a tiempo para entregarlo de tal manera que aún sea valioso para el destinatario.
No refactoriza el código cuando su refactorización no mejorará la calidad del código. La calidad no es subjetiva, aunque a veces, el diseño puede serlo.
No refactoriza el código cuando no existe una justificación comercial para realizar una modificación.
Probablemente hay más, pero espero que tengas la idea ...
La refactorización no es buena en sí misma. Más bien, su propósito es mejorar la calidad del código para que se pueda mantener de manera más económica y con menos riesgo de agregar defectos. Para el código desarrollado activamente, los beneficios de la refactorización valen el costo. Para el código congelado en el que no hay intención de seguir trabajando, la refactorización no produce ningún beneficio.
Incluso para el código activo, la refactorización tiene sus propios riesgos, que las pruebas unitarias pueden minimizar. También tiene su propio lugar en el ciclo de desarrollo, que es hacia el frente, donde es menos perjudicial. El mejor momento y lugar para la refactorización es justo antes de comenzar a realizar cambios importantes en algún código frágil.
No refactorice si no tiene tiempo para probar el código refactorizado antes del lanzamiento. La refactorización puede introducir errores. Si tiene un código bien probado y relativamente libre de errores, ¿por qué correr el riesgo? Espera hasta el próximo ciclo de desarrollo.
Para reforzar la otra respuesta (y tocar temas que mencionas): no refactorices una parte del código hasta que esté bien cubierto por todos los tipos de pruebas relevantes. Esto no significa "no refactorizarlo"; el énfasis está en "agregar las pruebas necesarias" (para realizar las pruebas unitarias correctamente puede ser necesario un cierto refactoring, en particular la introducción de DP de fábrica y / o DP de inyección de dependencia en Código que ahora está sólidamente atornillado a dependencias concretas).
Tenga en cuenta que esto cubre los problemas de su segundo párrafo: si una sección del código es crítica en el tiempo, debería estar bien cubierta por "pruebas de carga" (que, como el tipo más habitual, la prueba de corrección, debe cubrir ambas unidades específicas [aunque En lo que respecta al rendimiento, ¡la comprobación de la corrección es un asunto de otras pruebas! -)] Y operaciones de extremo a extremo: el equivalente de las pruebas unitarias y las pruebas de integración, si se habla de corrección en lugar de rendimiento.
El código multitarea con problemas sutiles de sincronización puede ser una pesadilla, ya que ninguna prueba puede hacer que te sientas completamente seguro al respecto, no se debe considerar ninguna otra refactorización (que podría afectar a cualquier sincronización frágil que parezca estar funcionando ahora) ANTES una destinada a hacer que la sincronización sea mucho, MUCHO más robusta y sólida (el paso de mensajes a través de colas con seguridad garantizada por subprocesos es, de lejos, mi patrón de diseño favorito a este respecto ;-).
Si el código parece muy difícil de refactorizar sin romperse, ¡ese es el código más importante para refactorizar!
Si no hay pruebas, escríbalas mientras refactorizas.
Honestamente, el único caso es en el que la administración / cliente / Alguien importante tiene prohibido tocar algún código y, cuando eso sucede, considero que el proyecto no funciona.
Si está atascado, debe mantener una base de código flakey anterior sin futuro más allá de mantenerla en funcionamiento hasta que la administración pueda morder la bala y hacer una reescritura, luego la refactorización es una situación de pérdida-pérdida. Primero, el desarrollador pierde porque refaccionar el código defectuoso es una pesadilla y, segundo, el negocio pierde porque el desarrollador intenta refactorizar las interrupciones del software de manera inesperada e imprevista.
Si se atiene al principio de que todo lo que haga debe agregar valor para el cliente / negocio, entonces las veces que no debe refactorizar son las siguientes:
- Código que funciona y no se planea ningún nuevo desarrollo.
- El código que es suficientemente bueno / funciona y la refactorización simplemente representa el chapado en oro.
- El costo de la refactorización es más alto que vivir con el código existente.
- El costo de la refactorización es mayor que volver a escribir el código desde cero
Algunos de los otros respondedores dicen que no debe refactorizar el código que no tiene pruebas de unidad. Si el código necesita refactorización, debe refactorizarlo, sin embargo, primero debe escribir las pruebas. Si el código está escrito de una manera que dificulta la prueba, debe reescribirse (en un mundo perfecto).
Siempre hay un equilibrio entre corregir o agregar al código y refactorizar. Sin embargo, este balance está tan a favor de la refactorización que no creo haber estado nunca en un equipo que haya refaccionado demasiado. Lo más probable es que, si crees que te estás equivocando demasiado por refactorizar, tienes razón en el dinero.
Por supuesto, el factor determinante más importante es qué tan cerca está la fecha límite. Si un plazo es inminente, los requisitos son lo primero.
Soy un gran fan de la refactorización para mantener el código limpio y mantenible. Pero, por lo general, querrá evitar refactorizar los módulos de producción que funcionan bien y no requieren cambios. Sin embargo, cuando necesita trabajar en un módulo para corregir errores o introducir una nueva función, por lo general vale la pena un poco de refactorización y no le costará mucho, ya que está comprometido a realizar un conjunto completo de pruebas y pasar por el lanzamiento. proceso. (Las pruebas de unidad son muy útiles, pero son solo una parte del conjunto completo de pruebas, como se señala en otros carteles).
Las refactorizaciones más significativas pueden dificultar que otros encuentren su camino alrededor del nuevo código, y luego pueden reaccionar desfavorablemente a la refactorización. Para minimizar esto, involucre a otros miembros del equipo en el proceso utilizando un enfoque como la programación en pares.
Actualización (8/10): otra razón para no refactorizar es cuando no se está acercando a la base de código existente con la humildad y el respeto adecuados. Con estas cualidades, tenderás a ser conservador y solo refactorizarás lo que realmente hace una diferencia. Si se acerca al código con demasiada arrogancia, puede terminar haciendo cambios en lugar de refactorizar. ¿El nombre del nuevo método es realmente más claro o el anterior tenía un nombre con un significado muy específico en el dominio de su aplicación? ¿Realmente necesitaba reformatear mecánicamente ese archivo fuente a su estilo personal, cuando el estilo existente cumplía con las pautas del proyecto? Una vez más la programación de pares puede ayudar.