¿Se debe actualizar el código más antiguo para usar construcciones de lenguaje más nuevas o se deben atascar las construcciones desactualizadas?

15

Quiero realizar algunas mejoras en algunos de los códigos aún funcionales que se escribieron hace mucho tiempo, antes de que el lenguaje de programación en el que está escrito aumentara en características. En teoría, todo el proyecto utiliza la versión actualizada del lenguaje; sin embargo, este módulo en particular (y, de hecho, muchos otros módulos) aún están escritos en el dialecto anterior.

Debería:

  • ¿No toco las partes del código que no tengo que tocar, pero escribo mi parche haciendo uso de las nuevas características de idioma que facilitan la escritura del parche pero no se usan en situaciones análogas en ninguna otra parte del módulo? (Esta es la solución que elegiría intuitivamente).
  • ¿Ignora el hecho de que pasaron los años y refleja el estilo que se usa en el resto del código al escribir mi parche, comportándome de manera efectiva como si estuviera haciendo la misma tarea muchos años antes? (Esta solución la consideraría tonta de manera intuitiva, pero dada la cantidad de problemas que todos los que hablan sobre el "buen código" hacen acerca de mantener la coherencia a toda costa, quizás esto sea lo que debería hacer).
  • ¿Actualizar todo el módulo para usar las construcciones y convenciones de lenguaje más recientes? (Esta es probablemente la mejor solución, pero puede requerir un montón de tiempo y energía que podría gastarse mejor en una tarea diferente).
pregunta gaazkam 25.03.2017 - 00:17

5 respuestas

10

Es imposible dar una respuesta definitiva a esta pregunta, ya que depende demasiado de los detalles de la situación.

La consistencia en el estilo de la base de código es importante porque ayuda a que el código sea más fácil de entender, que es uno de los aspectos más importantes de la capacidad de mantenimiento.
No serías el primer programador que fue maldecido al infierno por hacer que el código fuera difícil de entender al mezclar diferentes estilos. Incluso podría ser usted mismo quien haga la maldición dentro de un año.

Por otra parte, el uso de nuevas construcciones de lenguaje que no existían cuando se escribió el código por primera vez no implica automáticamente que esté reduciendo la capacidad de mantenimiento o incluso que esté rompiendo el estilo del código. Todo depende de las características del idioma en particular que desee utilizar y de lo familiar que esté el equipo con el estilo antiguo del código y las nuevas características.

Como ejemplo, generalmente no sería recomendable comenzar a introducir conceptos de programación funcional como map / reduce a un código base que está completamente en estilo OO, pero podría funcionar para agregar una función lambda aquí y allá a un programa que no No uses nada parecido antes.

    
respondido por el Bart van Ingen Schenau 25.03.2017 - 10:38
5

En gran medida, el código y su aspecto es irrelevante . Lo que hace el código es lo que importa.

Si puede garantizar que cambiar / reescribir el código no cambiará lo que hace el código, entonces puede continuar y refactorizar el código al contenido de su corazón. Esa "garantía" es un conjunto exhaustivo de pruebas unitarias que puede realizar antes y después de sus cambios, sin diferencias perceptibles.

Si no puede garantizar esa estabilidad (no ha realizado esas pruebas), déjelo en paz.

Nadie te agradecerá por "romper" una pieza de software crítico para el negocio, incluso si estuvieras intentando hacerlo "mejor". "Trabajar" triunfa "mejor" cada vez.

Por supuesto, no hay nada que le impida crear un conjunto de tales pruebas en preparación para tal ejercicio ...

    
respondido por el Phill W. 28.03.2017 - 12:30
3

Casi cualquier cosa puede analizarse en términos de costos y beneficios, y creo que esto se aplica aquí.

Los beneficios obvios de la primera opción son que minimiza el trabajo a corto plazo y minimiza las posibilidades de romper algo al reescribir el código de trabajo. El costo obvio es que introduce inconsistencias en la base del código. Cuando realiza alguna operación X, se realiza de una manera en algunas partes del código y de una manera diferente en una parte diferente del código.

Para el segundo enfoque, ya has notado el beneficio obvio: la consistencia. El costo obvio es que tiene que concentrarse en trabajar de una manera que de otra manera hubiera abandonado hace años, y el código permanece ilegible de manera constante.

Para el tercer enfoque, el costo obvio es simplemente tener que hacer mucho más trabajo. Un costo menos obvio es que puede romper cosas que funcionaban. Esto es particularmente probable si (como suele ser el caso) el código antiguo tiene pruebas inadecuadas para garantizar que continúe funcionando correctamente. El beneficio obvio es que (suponiendo que lo hagas con éxito) tienes un código nuevo y brillante. Junto con el uso de nuevas construcciones de lenguaje, tiene la oportunidad de refactorizar el código base, que casi siempre dará mejoras en sí mismo, incluso si todavía usó el lenguaje exactamente como existía cuando se escribió, agregue nuevas construcciones que hagan que trabajo más fácil, y puede ser una gran victoria.

Sin embargo, otro punto importante: en este momento, parece que este módulo ha tenido un mantenimiento mínimo durante mucho tiempo (a pesar de que el proyecto en general se está manteniendo). Eso tiende a indicar que está bastante bien escrito y relativamente libre de errores, de lo contrario, probablemente se haya sometido a más mantenimiento en el ínterin.

Esto nos lleva a otra pregunta: ¿cuál es la fuente del cambio que está haciendo ahora? Si está solucionando un pequeño error en un módulo que en general aún cumple con sus requisitos, eso indicaría que es probable que el tiempo y el esfuerzo de refactorizar todo el módulo se desperdicien en gran medida, para cuando sea necesario que alguien se meta con él de nuevo, pueden estar en aproximadamente la misma posición que usted ahora, manteniendo un código que no cumple con las expectativas "modernas".

También es posible, sin embargo, que los requisitos hayan cambiado, y estás trabajando en el código para cumplir con esos nuevos requisitos. En este caso, es muy probable que sus primeros intentos no cumplan con los requisitos actuales. También hay una posibilidad sustancialmente mayor de que los requisitos se sometan a algunas rondas de revisión antes de que se estabilicen nuevamente. Eso significa que es mucho más probable que esté haciendo un trabajo significativo en este módulo en el (relativamente) corto plazo, y es mucho más probable que realice cambios en el resto del módulo, no solo en el área que conoce. ahora. En este caso, es mucho más probable que la refactorización de todo el módulo tenga beneficios tangibles a corto plazo que justifiquen el trabajo adicional.

Si los requisitos han cambiado, es posible que también deba ver qué tipo de cambio implica, y qué está impulsando ese cambio. Por ejemplo, supongamos que estaba modificando Git para reemplazar su uso de SHA-1 con SHA-256. Este es un cambio en los requisitos, pero el alcance está claramente definido y es bastante estrecho. Una vez que haya hecho que almacene y use SHA-256 correctamente, es poco probable que encuentre otros cambios que afecten el resto de la base del código.

En la otra dirección, incluso cuando comienza pequeño y discreto, un cambio en la interfaz de usuario tiene una tendencia a aumentar, por lo que lo que comenzó como "agregar una nueva casilla de verificación a esta pantalla" termina más como: "cambiar esta IU fija para admitir plantillas definidas por el usuario, campos personalizados, esquemas de color personalizados, etc. "

Para el ejemplo anterior, probablemente tenga más sentido minimizar los cambios y errar por el lado de la coherencia. Para este último, es mucho más probable que la refactorización completa valga la pena.

    
respondido por el Jerry Coffin 27.03.2017 - 20:44
1

Iría por ti primera opción. Cuando codifico, sigo la regla para dejarlo en un estado mejor de lo que era.

El nuevo código sigue las mejores prácticas, pero no tocaré el código que no esté relacionado con los problemas en los que estoy trabajando. Si lo hace bien, su nuevo código debería ser más legible y fácil de mantener que el código anterior. Descubrí que la capacidad de mantenimiento total mejora, porque si continúa así, el código que necesita para su trabajo es cada vez más el código "mejor". Lo que lleva a una resolución más rápida de problemas.

    
respondido por el Pieter B 28.03.2017 - 12:43
1

La respuesta, como tantas otras cosas, es depende . Si hay mayores ventajas para actualizar las construcciones más antiguas, como una capacidad de mantenimiento a largo plazo enormemente mejorada (evitando el infierno de devolución de llamada, por ejemplo) que hacerlo. Si no hay una ventaja importante, la consistencia es probablemente tu amigo

Además, también querrá evitar la incorporación de dos estilos en la misma función más de lo que desearía evitarlo dentro de dos funciones separadas.

Para resumir: su decisión final debe basarse en un análisis de 'costo' / 'beneficio' de su caso particular.

    
respondido por el Orangesandlemons 28.03.2017 - 12:52

Lea otras preguntas en las etiquetas