El progreso impulsa la tecnología hacia adelante. Pero el progreso también tiene un costo: al agregar nuevas capacidades y características, la comunidad de desarrolladores ajusta constantemente los componentes básicos. Eso incluye los lenguajes fundamentales utilizados para codificar soluciones tecnológicas.
Cuando los componentes básicos cambian, el código detrás de la solución tecnológica también debe cambiar. Es un ejercicio desafiante y lento que agota los recursos. Pero, ¿y si hay una alternativa?
El problema: leer el código que escribió otra persona
Demos un paso atrás y echemos un vistazo a uno de los desafíos fundamentales en el desarrollo: editar el código de otra persona. Está bien editar el código que acaba de escribir o que escribió hace un par de semanas. Pero editar su propio código escrito hace años, no importa el código de otra persona, esa es una historia diferente.
Las reglas de estilo de código internas pueden ayudar, pero siempre hay convenciones de nomenclatura extrañas para variables y funciones, o elecciones inusuales para algoritmos. Podría decirse que la capacidad de un programador para leer código es una habilidad clave, pero es difícil para todos.
Los desarrolladores llaman al proceso de edición de código antiguo “refactorización” y es un proceso que comúnmente introduce nuevos errores o problemas de rendimiento. Por eso, retroceder y editar el código antiguo, bueno, eso es lo último que la mayoría de los equipos de desarrollo quieren hacer, especialmente cuando el código base existente se ejecuta de manera estable y está haciendo su trabajo.
Es un verdadero dolor de cabeza, pero a veces no hay alternativa
La refactorización es algo que todo desarrollador quiere evitar durante el mayor tiempo posible porque puede parecer una pérdida de tiempo. No obstante, los desarrolladores deben refactorizar de vez en cuando por una variedad de razones, y una de las razones más comunes se debe a los cambios en los componentes básicos del desarrollador.
Eso incluye cambios en los lenguajes de programación utilizados para crear software, que inevitablemente evolucionan con el tiempo. Las nuevas versiones de un idioma a menudo dejarán de lado las viejas formas de hacer las cosas e introducirán nuevas funciones. Si los desarrolladores no adoptan la nueva versión de idioma, quedan excluidos del nuevo conjunto de características.
Sin embargo, el código existente generalmente necesita un ajuste para ejecutarse en la nueva versión del lenguaje, y eso implica un proceso de refactorización. Y ese es el enigma: para adoptar la versión nueva y más avanzada de un lenguaje, los desarrolladores deben refactorizar, y en el camino gastarán una gran cantidad de esfuerzo y romperán todo tipo de cosas inesperadas, introduciendo nuevos errores en una aplicación que estaba funcionando bien.
Peor aún, la refactorización por sí sola no le brinda las ventajas de la nueva versión del idioma, sino que necesita volver a desarrollar su base de código para aprovechar las mejoras. De lo contrario, a pesar de ajustar el código para que se ajuste a la nueva versión del idioma, estará donde solía estar: una base de código que se ejecuta en una nueva versión del idioma, pero sin características nuevas.
Los proveedores suelen dejar que los usuarios finales se encarguen de ello.
Puede parecer un ejercicio sin sentido pero, con la marcha constante del cambio tecnológico, a menudo hay pocas opciones al respecto: sus socios tecnológicos eligen por usted.
Digamos que acabamos de pasar de Python 2.7 a Python 3.0. Si está desarrollando sus aplicaciones internamente, tiene el control total y puede hacer el cambio o no hacerlo. Los desarrolladores, por otro lado, bien pueden decidir dejar las cosas como están. Si una aplicación se desarrolla y se ejecuta en Python 2.7, el desarrollador simplemente lo dejará así y les dirá a los usuarios que se desarrolló una aplicación para Python 2.7, sin soporte para otras versiones.
Puede dejar a los usuarios en una situación difícil: permanecer en la versión anterior de Python 2.7 para acomodar la aplicación, dejando atrás el progreso, o cambiar a Python 3.0 y correr el riesgo de una serie de incompatibilidades con las aplicaciones.
El resultado neto: un gran riesgo de seguridad
Los lenguajes de programación (y sus variadas bibliotecas) no son inmunes a las vulnerabilidades de seguridad. Cuando surgen estas vulnerabilidades, los desarrolladores pueden imponerle una actualización de la versión de idioma.
Pero estas actualizaciones no se limitarán a correcciones de errores simples: provocarán la desaprobación de las construcciones del lenguaje con nuevas construcciones incorporadas, y eso obligará a los desarrolladores a realizar los movimientos de hacer cambios en el código existente, nuevamente con todos los problemas potenciales que trae.
La situación empeora aún más cuando piensa en el efecto compuesto de las bibliotecas incluidas. Después de los cambios de idioma, estas bibliotecas también deben actualizarse, pero si los autores no actualizan una de las bibliotecas en uso, el desarrollador no podrá usarla después de actualizar el resto del código a una versión más reciente, lo que nuevamente lleva a más escritura de código.
Es fácil ver a dónde lleva todo esto: más esfuerzo, riesgos adicionales de introducir errores… y una reticencia a seguir refactorizando para acomodar las actualizaciones. ¿Próximo? Las actualizaciones simplemente no se realizan, lo que significa que las cargas de trabajo dependen de componentes básicos inseguros y obsoletos.
La historia es similar a lo que vemos en todo el mundo de la tecnología, ya que los componentes básicos antiguos y vulnerables dejan la puerta abierta a los ataques cibernéticos. Sin embargo, están surgiendo algunas buenas noticias.
¿Hay una solución mejor?
Tome los sistemas operativos no compatibles, por ejemplo. En el pasado, cuando un sistema operativo llegó al final de su vida útil, la única opción era actualizar a un sistema operativo más nuevo: una inversión importante y llena de riesgos. El resultado neto es que muchas organizaciones confían en sistemas operativos sin parches ni soporte, incluso para cargas de trabajo críticas. Si no tiene aplicaciones actualizadas, debido a que los desarrolladores no refactorizarán las bases de código antiguas, no puede mover sus aplicaciones a sistemas operativos más nuevos que no son compatibles con las versiones anteriores del lenguaje y, por lo tanto, romper la aplicación.
Afortunadamente, este escenario cambió a medida que El soporte al final de la vida es ahora una realidad para muchos sistemas operativos Linux.lo que significa que las organizaciones pueden ganar tiempo para migrar de un sistema operativo no compatible a un sistema operativo con soporte oficial del proveedor, sin correr ningún riesgo de seguridad.
¿Se puede hacer algo similar para las versiones de idiomas? ¿Una forma de “actualizar” efectivamente un tiempo de ejecución de idioma con las últimas correcciones de seguridad y, al mismo tiempo, no cambiar el funcionamiento de esa versión de idioma o bibliotecas específicas, eliminando así la necesidad de refactorizar?
Repetir lo que se ha logrado para los sistemas operativos y aplicarlo a las versiones de idiomas les dará a los desarrolladores un enorme respiro, reduciendo la necesidad de refactorizar continuamente. A su vez, existe una mayor probabilidad de que las cargas de trabajo se ejecuten de forma segura.
¿Es posible? Bueno, lo que se logró para los sistemas operativos se puede expandir a otras áreas. Mira este espacio.