Funciones: este error es más caro que "nulo"

Todos los días utilizamos un patrón de programación que aumenta innecesariamente el costo de creación y mantenimiento de software. Conduce a innumerables errores y vulnerabilidades de seguridad. Requiere una refactorización constante. Es difícil de probar, tedioso de documentar y su flexibilidad convierte cada implementación en un copo de nieve único, lo que lleva a una duplicación de código sin fin.



El nombre de esta plantilla es función.



Más específicamente, es una interfaz, que suele ser una colección de funciones.





¿Qué idiomas has aprendido?



Uno de los primeros cuando aprendemos a programar, aprendemos el principio de lógica reutilizable. Esto invariablemente nos lleva a funcionar: el componente básico de todo proyecto de software. Las características en sí mismas no son tan malas, pero es precisamente porque se usan como un componente reutilizable que escribir, mantener y escalar el software se vuelve tan costoso.



¿Por qué?



Escribir código reutilizable es difícil.



No, no es así. Esto es inaceptable.



Cualquier desarrollador puede escribir código reutilizable, independientemente de su experiencia. Los lenguajes como JavaScript, Python, Ruby y Go se componen de millones de pequeños módulos comunes que demuestran la facilidad de escribir código fuente simple y reutilizable. Es fácil escribir código reutilizable .



Refactoricemos esta declaración.



Escribir código reutilizable es difícil. Difícil de reutilizar el código.



Pero este tampoco es el caso. Eche un vistazo a la biblioteca node.js repeat-string



en npm. No hace más que repetir la línea y los desarrolladores la descargan diecisiete millones de veces a la semana.





Número de descargas de cadena repetida en npm



Diecisiete millones es solo el número de descargas. Este número no nos dará idea de cuántas veces se usa esta función en el código fuente. ¡La cantidad debería ser astronómica!



Entonces, ¿qué estoy haciendo?



¿Cómo puede encontrar un módulo como repeat-string



para su proyecto node.js? Busque "repetir cadena" en npm . Tal vez ingrese "repetición de cadena", pero los resultados serán similares. El problema del que estoy hablando se puede ver en el segundo resultado de búsqueda. Y en el cuarto, y en el noveno, y en el décimo, y en el undécimo.



Eche un vistazo a estos ejemplos. Cada biblioteca proporciona un comportamiento completamente idéntico.





Ejemplos de bibliotecas de repetición de líneas npm



¿Ves cuál es el problema?



No, no es que uno de ellos sea asincrónico por alguna razón desconocida. Sin mencionar que la repetición de cadenas ha sido parte del lenguaje JavaScript ( "A".repeat(5)



) durante más de seis años . El problema es que cada biblioteca es diferente:



  1. En la firma de los datos entrantes. Algunos pueden recibir (string, int)



    , otros pueden recibir (int, string)



    . Uno acepta números de coma flotante, el otro requiere una función de devolución de llamada.
  2. En la firma de la salida. Cada biblioteca imprime una cadena, excepto una, que no imprime nada y pasa su resultado a la función de devolución de llamada. Y no me dejes ni empezar a analizar sus errores.
  3. En el comportamiento cuando se ejecutan. Uno es asincrónico, los otros son sincrónicos.
  4. Por el método de conceder acceso. Algunos proporcionan acceso a una única función exportada, otros proporcionan una función como método de un objeto.


Puede culpar a JavaScript por varias razones, pero esto no es un problema con el idioma. Debido a la popularidad de JavaScript y las limitaciones de sus bibliotecas estándar, este problema es tan común que pude demostrarlo con un ejemplo tan simple como la repetición de cadenas. Por otro lado, nada me impide recrear todas estas diferencias en cualquier otro idioma. Este es un ejemplo muy simple, pero a medida que la funcionalidad se vuelve más compleja, estas diferencias se vuelven aún más pronunciadas.



¿Por qué es esto un problema?



El problema es que tal cantidad de opciones no crea ningún valor , solo problemas por sí solos. No afectan la "lógica empresarial" (es decir, lo que importa en primer lugar). Estos son los detalles de implementación. A veces, estas opciones surgen de la falta de algo en el lenguaje o el marco y, a veces, son solo elecciones espontáneas. Estamos tratando de elegir una opción que simplifique el trabajo del desarrollador ahora o en el futuro, pero es imposible predecir el futuro. Estas soluciones son verdaderamente diabólicas: cada opción que elijas parece buena al principio, mientras que todo funciona. Recibimos un impulso de dopamina y sentimos que estamos en la cima del mundo. ¡Señores de todos los sistemas! Sin embargo, cuando necesitamos agregar, reemplazar o cambiar algo, nos damos cuenta de que no éramos tan genios.



¿Con qué frecuencia necesitamos cambiar algo? Cada día. Esto es lo que estamos haciendo. ¿Con qué frecuencia se rompe el software debido a esto? Literalmente cada vez. A veces, la avería es menor y la solucionamos con poco esfuerzo. Hemos llegado a un acuerdo con el hecho de que el software defectuoso es normal. Incluso cuando escribimos pruebas automatizadas que no hacen más que comprobar que algo está roto.



El problema con las interfaces surge del hecho de que un programador puede tomar muchas decisiones durante el proceso de desarrollo. Decisiones como elegir entre parámetros posicionales, configuraciones y enlazadores, asincrónico versus síncrono, global versus local, con estado versus sin estado, constructores versus fábricas, enfoque funcional versus orientado a objetos y un número infinito de otras opciones. Cada elección está determinada por las mejores prácticas modernas y cada una se convierte en un grano de arena atrapado dentro del mecanismo.



Este problema no es nuevosin embargo, lo toleramos y enseñamos este enfoque a cada nueva generación. ¿Por qué? El problema no es que tomemos decisiones equivocadas, sino que se nos presentan malas opciones. Cada opción es un caleidoscopio de compensaciones y la respuesta correcta depende del punto de vista. Cuando todo es un compromiso, siempre hay una mejor opción . Siempre puedes reescribir tu código para mejorarlo.



Refactoricemos nuestra declaración por tercera vez.



Escribir código reutilizable es difícil. Difícil de reutilizar el código. Es difícil escribir código reemplazable.



Esta afirmación no es tan atractiva, pero más cercana a la verdad.



Sin código para pegar, necesitamos planchar cada pliegue de la interfaz antes de poder usarla. Debe personalizar cada fragmento de código que se incluye en la aplicación. Cada entrada. Cada conclusión. Cada API. Colocamos enlazadores en adaptadores y los envolvemos en fábricas basadas en servicios. Pero ninguna cantidad de maquillaje hará que su patrón de diseño se vea bonito .



Es como si estuviéramos construyendo software en el siglo XVIII. Vimos manualmente los árboles en tablas de cualquier tamaño. Hacemos martillos y perforamos clavos desde cero solo para construir una casa que se vea exactamente como la siguiente. Cuesta demasiado y lleva demasiado tiempo. Incluso después de la finalización del proyecto, la carga del apoyo nos empuja al suelo. Las dimensiones no son estándar, el cableado impacta a los electricistas y a los constructores que acaban de graduarse de la escuela vocacional no les gusta la forma en que hicimos los clavos. Ya es hora de que Leroy-Merlin y el 2x4 digital aparezcan en el mundo del software.





“Hola, mi nombre es Tim. Trabajo como líder tecnológico en Google, tengo 30 años de experiencia en codificación, pero tengo que averiguar cómo obtener la longitud de una cadena en Python ".



¿Necesita ayuda con alguna API para buscarlo personalmente constantemente ?




No será una sorpresa si digo que podríamos tener estándares que sean lo suficientemente buenos para todos. Microsoft introdujo la tecnología COM en los años 90 para intercambiar lógica entre aplicaciones escritas en cualquier idioma. La tecnología JVM tiene casi la misma edad y ha demostrado cuántos lenguajes pueden manejar el mismo código de bytes y también interactuar entre sí. El mundo sigue redescubriendo Flow durante décadas y Linda como una forma de vincular cajas negras distribuidas entre sí, y Docker es una nueva forma de ver lo que puede ser una caja negra moderna.



Este problema presenta muchas posibilidades y muchos están tratando de resolverlo. Dapr y WasmCloud parecen nuevas soluciones prometedoras ... Resuelven parcialmente el problema de diferentes maneras. Por más triste que sea el estado actual del desarrollo de software, tengo más esperanzas hoy que en los últimos 10 años. Este breve período de promesas emocionantes provino de JavaScript, que prometió crear una plataforma universal en la que las aplicaciones amorfas podrían extenderse por todo el mundo, pero como resultado, se convirtió en un montón de Electron, React y RAM desperdiciada. Para mí, Web Assembly se ha convertido en una nueva fuente de optimismo. Está lejos de ser ideal, pero también es maravilloso. El ideal nunca gana.






Publicidad



¿Busca un servidor en alquiler para depurar proyectos, un servidor para desarrollo y hosting? Definitivamente eres nuestro cliente :) Facturación diaria de servidores, crea tu propia configuración en unos pocos clics, anti-DDoS ya está incluido en el precio.



Suscríbete a nuestro chat en Telegram .






All Articles