Cuenta la historia que, hace muchos años, cuando los programadores eran hombres y se escribían sus propias rutinas, clases, funciones y módulos, un fenómeno conocido como reutilización de código comenzaba a volverse hip, igual que las canciones de MC Hammer, los trolls y otras cosas espantosas de la epoca. Para entonces, los más viejos, y no por ello sabios, arraigados a sus ortodoxas, anticuadas y puercas formas, sufrían de lo que se le conoce hoy como el «Not Invented Here» syndrome, o el síndrome de «No se hizo aquí» que significa, en breve, solo utilizar recursos propios de la empresa y evitar a toda costa aquellos de externos, palabras más, palabras menos.
The «Not invented here» syndrome
Desarrollar software es una de las disciplinas más complejas que existen. Quien se dedique a esta biznaga lo sabrá, y quienes no probablemente no lo comprenderán. Y es que, como siempre comento, para desarrollar software útil uno debe no solamente entender su propia profesión relacionada con código, lenguajes de programación, lógica, razonamiento, matemáticas, cálculo y demás chunches sino que además debe entender perfectamente bien el negocio para el cual está desarrollando el producto, sería tonto pensar que solo con saber ciencias computacionales podríamos ser útiles a la sociedad. Para realizar un artefacto (virtual, en este caso) que ayude a mejorar el flujo de trabajo, ahorrar tiempo y eficientar procesos de otros sectores laborales es imperante que uno como ingeniero en software, programador o desarrollador entienda perfectamente bien el problema que intenta solucionar, de hecho, y la mayoría de las veces, aun mejor que quien nos paga para solucionar dicho problema.
Habiendo entonces tantos problemas que solucionar, diagramas que diseñar, juntas, análisis, levantamiento de requerimientos, etc. queda, sino mínimo, sí muy limitado tiempo para hacer lo que nos gusta, «tirar código«, como dicen mis colegas, y es por esta razón que conforme la computación se volvió mas accesible y sobre todo el Internet, se propuso, de manera extra oficial, ayudarnos los unos a los otros, como dice por ahí en algunas escrituras.
Verán, el hecho de reutilizar el trabajo de otros no es nada nuevo. Una de mis frases favoritas, y probablemente lo he dicho un millón de veces es aquella de Sir Isaac Newton, aplicable siempre a muchos de mis posts:
If I have seen further than others, it is by standing upon the shoulders of giants
Mi estimado Isaac se refiere al hecho de que, reutilizando y apoyandose en el trabajo de terceros es posible progresar, de alguna manera, el poder invertir nuestro preciado tiempo solucionando otros problemas nos permite tener mejores resultados, es decir, si ya existen motores que nos permiten mover vehículos es más inteligente reutilizar las leyes de la física, comprobadas, de un motor de bobina o de combustión que reinventar uno nuevo basado en alguna otra cosa. «If it works, don’t try to fix it» es el motto de muchos ingenieros.
Sin embargo, a pesar de esta filosofía, existe aún mucho programador decidido a utilizar solamente su código o aquel de sus colegas propios del mismo empleador. Verán, el programador es un animal sumamente ególatra, celoso de su trabajo y posesivo y hará lo que sea para demostrar que sus dancing moves son los mejores, aun cuando, francamente, a nadie le importa. Lo anterior se conoce como el not invented here syndrome, o el sindrome de «No está hecho aquí» y aunque cada vez se ha vuelto menos común esta actitúd, aun existe, sobre todo en aquellos de la vieja escuela, no dispuestos a aceptar que hay alguien que probablemente lo haya hecho mejor que nosotros.
El sindrome de «No está hecho aquí» se ha desterrado de muchas industrias a lo largo de los años, no solo de la del desarrollo de software, por ejemplo, hace años, cualquier empresa de manufactura de electrónicos probablemente diseñaría la mayoría de los dispositivos, microcontroladores, tarjetas y chips de una televisión, hoy en día esta misma industria probablemente solo ensamble componentes, hechos en diferentes empresas, de diferentes países, globalización le llaman. ¿Por qué? Bueno porque permite una línea de ensamble muy rápida a menores costos lo cual se traduce a mejores ganancias, o sea lana.
Por otra parte, el hecho de tener enfocado a un equipo de trabajo o empresa en un área específica es sumamente redituable ya que especializa a dicho equipo o empresa a ser líder en su sector o ramo específico y sobre todo de invertir tiempo, dinero e investigación en problemas muy particulares mientras que su vecino de nave industrial hace lo mismo; dedicarse a resolver otros problemas muy particulares.
En nuestro estado, Baja California, existen infinidad de fábricas, o maquilas, como se les conoce, que se dedican a mercados verticales muy específicos, por ejemplo, asientos para aviones, marcos para ventanas, cajas de cartón. Si! Uno podría pensar, y bueno ¿Quién estaría interesado en fabricar marcos para ventanas exclusivamente? Bueno, toda la industria de construcción, hotelera, compañías dedicadas a materiales y muebles, etc. El beneficio es que quien se encarga de uno de estos mercados verticales lo hará perfectamente bien con procesos muy eficientados y esto se vuelve una cadena donde al final la suma de esos mercados verticales se traduce a un producto final para el consumidor de calidad.
El software no es muy diferente a estas otras industrias. Una aplicación requiere de infinidad de componentes y módulos que bien nos pueden llevar años terminar, es por ello que también existen casas de desarrollo y empresas dedicadas a vender productos para nosotros, los programadores, que podemos ensamblar y agregar extras para tener una aplicación útil para el consumidor en un tiempo relativamente corto, el tiempo es dinero así que entre más rápido se saque un release es mejor.
Recuerdo mis primeros pininos intentando hacer algo útil con un lenguaje de programación. Era más difícil de lo habitual, tenía uno muy pocas herramientas a la mano y había que hacer casi todo «a pata». Alguna vez intenté hacer una aplicación de chat, que se conectara a la recién nacida red de Microsoft MSN, sin embargo, conforme pude juntar los requerimientos para mi aplicación en Visual Basic 6, me dí cuenta que inevitablemente tendría que programar un módulo de sockets TCP para realizar dicha comunicación. Logré realizar un pequeño cliente capáz de iniciar sesión y enviar mensajes, nunca recibirlos. Al final decidí que era más complicado de lo que parecía y tiré la toalla, de cualquier modo ni siquiera me pagaban por ello.
Si hubiera tenido el cuerno de la abundancia de componentes de terceros que existen ahora, y que permiten solucionar problemas muy específicos, otro gallo me hubiera cantado.
Los años dorados
Tiempo después de mis intentos (o varios) de aplicaciones, hace unos 15 años ya, el Internet mejoró no solo la comunicación de los mortales, como nos gusta llamarle a los usuarios comunes a nosotros los geeks, sino que además permitió a quienes ya estábamos metidos en esto volvernos más creativos; salas de chat de temas específicos donde podíamos compartir ideas, foros de Internet donde hacer preguntas cuando alguien estaba atorado en alguna parte de su código y claro, componentes o software de terceros, bien sea pagados o descargados, «de prestado» de algún FTP.
Por ejemplo, mi primer lenguaje de programación oficialmente fue Pascal, con Turbo Pascal de Borland. Aplicaciones de consola en Ms-Dos. No había mucha creatividad que explotar. Tiempo después me di cuenta que no llegaría muy lejos con dicha herramienta y me pasé Visual Basic 6 ya que era lo más fácil de tomar para alguien de la epoca, bien era esto, Visual C++ o Delphi. ¿Por qué no pasarme directamente a Delphi, si era la evolución natural de Turbo Pascal, con la misma empresa, y el mismo lenguaje que ya conocía pero orientado a objetos? Bueno, por los componentes!
Aquellos eran tiempos dorados para ambas empresas. Por una parte, Borland tenía con Delphi sus VCL’s que permitían crear interfaces de usuario en poco tiempo y con mucha funcionalidad, Microsoft Visual Basic 6 incluía ya también componentes que encapsulaban elementos de GUI’s que nos llevarían meses pulir en MFC de Visual C++. ¿El resultado? Bolsillos llenos de dinero tanto para ISV’s como para quienes extendían estos componentes y los vendían como 3rd party libraries listas para usarse, justo como tu madre dejó de hacer caldo de pollo para el guisado y comenzó a comprar cubos de Knorr Suiza.
La segunda ronda
Poco duró el gusto a quienes se estancaron desarrollando aplicaciones para el escritorio. Conforme hubo más Internet y velocidades de acceso más rápidas las aplicaciones web se volvieron un estandard, y con ello, las interfaces de usuario basadas en nuevas tecnologías como HTML con CSS para el diseño y Javascript para la interacción con el usuario. Pero así como Delphi, Visual Basic 6 y Microsoft Visual C++ tenían sus pormenores dependiendo la versión del sistema operativo, del compilador y de las librerías así nos pasó con el desarrollo web: diferentes versiones de navegadores suponían (y suponen aun, hasta el día de hoy) problemas de compatibilidad entre el mismo código, es parte de nuestro trabajo sí, pero lo hace más complicado, y nos quita tiempo, es una de esas cosas las cuales optamos por dejarle a alguien mas resolver mientras nosotros nos enfocamos en solucionar los problemas para los cuales nos ha pagado nuestro cliente o nos pagara nuestro usuario final.
Es así como nacen librerías como Dojo Toolkit, jQuery, script.acolo.us y otras que nos permiten encapsular funcionalidad general para varios navegadores y desarrollar interfaces de usuario compatibles entre distintos entornos de una manera fácil.
El web developer vs el programador
Hay quienes onerosamente y con mucho orgullo se hacían llamar web developers. Una especia de nueva profesión nacida del programador de hobbie y con fuertes influencias de aquellos programadores de Visual Basic 6, a quienes seguramente estoy ofendiendo con la comparación, pero veamos, alguien que se dedica al «desarrollo web» suele ser usualmente alguien que:
- Viene de la industria del diseño o alguna otra área creativa, completamente diferente a la del desarrollo de software
- Busca maximizar la productividad con el esfuerzo mínimo
- Entiende conceptos básicos de programación pero no el ciclo de desarrollo de software o teorías computacionales
Por otra parte, quienes se bautizaron en la industria del software con tecnologías como Visual Basic 6:
- Tendían a ser personas con estudios técnicos con mucha práctica y poca teoría
- Buscaban entregar productos con la mayor cantidad de características con el esfuerzo mínimo
- Encapsulaban la mayoría de la carga pesada en el código de sus aplicaciones en componentes de terceros
Siendo que las industrias y sectores ajenos al del software no logran comprender la complejidad del nuestro, es común que buzzwords como web development se vuelvan una moda y se invierta buena cantidad de dinero en ser parte del movimiento, tal como en estos días todo es la nube, para gerentes, CTO’s y otros ejecutivos.
Y como vivimos en la selva y cada quien se tiene que rascar con sus propias uñas, no era raro que quienes ayudados por estos componentes de terceros, content management systems como joomla, drupal o wordpress y conocimientos básicos de programación se hayan vendido como… bueno, web developers.
A diferencia de un web developer, un programador suele conocer los fundamentos del desarrollo de software, metodologías, herramientas y teorías de ciencia computacional que al otro le parecen bien aburridas, pérdida de tiempo o simplemente difíciles de comprender.
Si bien un buen programador e inteligente, usará el trabajo de otros para agilizar su trabajo, conoce el balance entre uso y abuso porque, creanlo o no, como todo en esta vida, es posible abusar también del trabajo de terceros.
El sindrome de «Está hecho aquí«
Hace apenas unos días, una situación que ocurrió en el trabajo, me hizo pensar y motivó a escribir este artículo. Era día de release o entrega al cliente, se probó una nueva versión del producto, todo parecía haber funcionado a la perfección tanto en el equipo del desarrollador de frontend encargado de este feature como en la mía al momento de hacer QA, se realizaron pruebas también en el servidor de producción de este feature, todo funcionaba correctamente.
Pasó el fin de semana y recibí un correo de nuestro cliente indicando que uno de los features no funcionaba. Pensé que algo mal habría hecho el cliente ¿Qué podría haber fallado? Es decir, pruebas en todos los entornos se realizaron sin que este feature en especial hubiera fallado.
El lunes al llegar a la oficina probamos el deployment hecho al servidor, efectivamente había un problema en una de las páginas, problema que NO se manifestó cuando inicialmente se hizo el deployment a producción. Después de un par de horas encontramos el problema, problema que fue causado por el framework de UI que utilizamos, AngularJS.
¿Cómo pudo haber pasado esto?
Muy sencillo, a pesar de haber probado el feature A, contra el entorno de producción, y sin problemas, posteriormente se hicieron otras actualizaciones totalmente diferentes al feature A y que de ninguna manera afectaban su funcionamiento, sin embargo hubo un factor diferente, ajeno a nuestro propio código: el script que se corre cada vez que actualizamos realiza un build o empaquetado del frontend por medio de bower:
bower install && bower update
Si, el culpable estaba ahí, no en nuestro código, sino en uno de los (muchos, muchísimos) plugins que utiliza AngularJS, específicamente uno encargado de las rutas de la aplicación.
Una de las veces que se ejecutó este comando, después de haber probado feature A, se actualizó el plugin dejando este feature A, que ya se había probado, con problemas. Es decir, la actualización de código que no controlamos introdujo un problema.
¿Cómo pudimos solucionarlo?
Básicamente tuvimos dos opciones:
- Actualizar el plugin, volviendo a ejecutar el comando, pues ya existía una nueva versión con este fix aplicado
- Ajustar la versión a una específica dentro de nuestro proyecto, a una que sabemos funciona sin problemas, de manera que bower no actualice nunca el plugin
Y, temporalmente, decidimos aplicar la opción 1, en lo que lograbamos entender realmente el problema y buscar una solución adecuada y de largo plazo.
¿Nos hemos vuelto holgazanes como programadores?
Esta es una pregunta que me hago, y les hago a mis compañeros de trabajo, en repetidas ocasiones. Tal como en algún momento, los programadores de Visual Basic 6 abusaron de los componentes de terceros siento que aun, en pleno 2015, seguimos aplicando las mismas tendencias y malas prácticas, las trajimos del desarrollo de software de aplicaciones de escritorio a las aplicaciones web.
Si bien no estoy en contra de librerías que encapsulan funcionalidad para manipular el DOM entre navegadores, object relational mappers para acceso a base de datos, etc. sí estoy en contra de su abuso.
Alguna vez en uno de mis anteriores empleos, mientras desarrollábamos una aplicación en ASP.Net, uno de mis compañeros, encargado de la parte de UI decidió que era buena idea agregar un DLL como dependencia extra para ahorrarnos trabajo en la generación de cierta parte del código, y, ¿Cuál era esa parte? Un menú, un menú de 5 elementos, una simple lista con 5 enláces para el cual agregamos una dependencia de 1.2Mb solo porque mi colega era demasiado huevón (o inútil) para agregar unas 20 líneas de código HTML y CSS para crear dicho menú pero, oh, nuestro componente incluso tenía un editor visual!
Esta misma aplicación, con esta dependencia contaba además con:
- jQuery
- Dojo
- ASP.Net Ajax Toolkit
- Otros…
Y esto solo como parte del UI. Podrán imaginarse la aplicación entera, dependencia sobre dependencia, con tiempos de compilación ridículos para lo que debía hacer nuestra aplicación.
La razón por la cual se utilizaron tantos frameworks y librerías es que algunos implementaban features que otros no tenían, es decir, siempre se buscó la manera de complementar la falta de características o plugins de uno con el de otro, pero jamás les pasó por la cabeza la solución mas cercana, obvia y al final del día razón para la cual nos habían contratado: programarlo nosotros mismos.
Hay quienes podrán criticarme y mencionarme términos como DRY, KISS y otros principios de desarrollo y yo les digo: fuimos contratados para programar y resolver problemas.
Es decir, no somos una línea de ensamble, aunque existan empresas que claramente eso quieren y necesitan. Aun, particularmente en entornos donde no necesariamente se vive un ambiente de «maquila de software» se vive un frenesí casi absurdo de dependencia de terceros, donde si utilizamos algo hecho por nosotros esté probablemente mal, porque, ¿sábes? alguien más ya lo hizo en github, pero ¿lo has probado? No! pero no voy a complicarme…
Herramientas como nuget, composer, gems, npm y demás si bien nos han facilitado la vida también nos han vuelto holgazanes, esperando siempre que alguien más resuelva nuestros problemas.
A esta holgazanería la he bautizado como «El sindrome de está hecho aquí», queda estrictamente prohibido utilizar nuestro código en primer plano de prioridad porque, somos tontos, inferiores y menos inteligentes que cualquier otro indivudo en github.
Las consecuencias de la co-dependencia absurda en tiempos modernos
¿Existen consecuencias de abusar del uso de estos componentes de terceros? Claro! De hecho, todos los extremos son malos, ustedes saben, el ying y el yang.
Una de las cosas que hacen más estables a sistemas como Linux es la filosofía UNIX: cada componente del sistema debe realizar una tarea específica, y realizarla bien. El problema es que que ya no vivimos en tiempos de UNIX cuando los hombres eran hombres, y los programadores programaban. La facilidad y encapsulación de los nuevos lenguajes de programación de muy alto nivel nos han vuelto maquinas ensambladoras y menos pensadores, cuando se desarrollaron la mayoría de las herramientas base de UNIX había otro pensamiento entre el mundo de los ingenieros.
Aun cuando consideramos que cada componente debe realizar una tarea específica y bien hecha y que seguramente quien realizó dicho componente puso empeño en realizarlo con altos estándares de calidad, existen problemas naturales derivados de que quien realizó dichos componentes sufre de un mal común: ser humano. Los humanos no somos perfectos y nos equivocamos así que es muy común que nuestro software contenga bugs o problemas con cada versión, es entendible y natural.
El problema real se asoma cuando, en la búsqueda de volvernos más productivos, nos volvemos consumidores enfermizos del trabajo de otros. Una de las razones por las que más se quejaban los usuarios de aplicaciones a finales de los 90’s y principios de los 2000’s, sobre todo en entornos de Microsoft Windows era la poca calidad y estabilidad de los productos. ¿Adivinen quienes eran los culpables? DLL’s, librerías de terceros, componentes hechos fuera de casa. Mientras que el fabricante de dicho software esperaba ansiosamente una actualización de dicha librería para solucionar el problema, problema que naturalmente estaría fuera de sus manos resolver pues era código sobre el cual no tenía experiencia, ya habría pasado suficiente tiempo para que tanto el producto como el fabricante fueran tachados como mala calidad, chafa, chino, etc.
No mucho ha cambiado desde entonces ya que solo nos movimos a otras plataformas. He visto aplicaciones web «modernas» utilizar librerías de terceros de una manera abusiva, helpers de bases de datos que agregan megabytes y megabytes a nuestro build solo para realizar algunas pocas validaciones, 35 plugins de node para poder hacer funcionar un pequeño componente de UI en angular.
Tal como los programadores, en su momento, y aun en dias actuales, de C++ y otros lenguajes de mas bajo nivel no temen crear sus propias librerías, frameworks y utilizar componentes de terceros cuando es estrictamente necesario así quienes nos dedicamos a desarrollar aplicaciones web y otras plataformas no deberíamos temer aplicar nuestros conocimientos para crear software inteligente y no solo ensamblarlo, basado en código de otros, código que en cualquier momento puede fallar y del cual no solamente no tenemos el suficiente conocimiento para mantener sino además los recursos.
La colaboración es una de las cosas más extraordinarias que nos ha dado el Internet y las tecnologías distribuidas y hacen nuestro trabajo emocionante e interesante, pero también pensar como solucionar problemas propios y no temer a hacer lo que se supone sabemos hacer es una de las cosas más gratificantes que puede haber, aun cuando podamos pensar que alguien más lo hizo mejor que nosotros. Nunca debemos subestimarnos, pero sobre todo, nunca hay que dejar de sorprendernos a nosotros mismos con lo que podemos hacer individualmente o en un mismo equipo de trabajo.
Y es que colaborar no es un delito pero la mente humana está desarrollada para tomar las mejores decisiones si el sujeto u objetivo en cuestión es uno mismo, ¿Cómo podría siempre, alguien más, decidir la mejor manera de hacer algo?
Existe una anécdota extraída del libro Gabby: A story of courage and hope, de Gabrielle Giffords y Mark Kelly, este último, piloto de la NASA quien llevó varias veces el transbordador allá arriba y esposo de la primera, ex-congresista de EUA y quien recibió un disparo en la cabeza en Arizona hace unos años:
as the doctor described the massively invasive surgery his wife would require, Kelly thought back to the poor decision-making at NASA that had resulted in two fatal accidents. Post-Challenger and -Columbia, NASA set up a conference room to facilitate good decision-making. One wall bears the warning «None of us is as dumb as all of us.»
Determined not to let the medical team march off in lockstep, Kelly gathered all the doctors and residents in a small break room at the hospital. «At NASA, one thing I’ve learned is you can’t ask the space shuttle commander or the flight director or the chief engineer their opinion first. You’ve got to seek out the opinion of the junior people,» said Kelly. So he chose the youngest looking person in the room–an opthamology resident–and asked for her opinion on the injury and procedure. He then went around the room until everyone had had a chance to voice their views. Ultimately, the doctors performed the operation.
Tal como Kelly lo menciona, «None of us is as dumb as all of us» así que quizá, y solo quizá, si de vez en cuando individualizamos nuestro trabajo como ingenieros de una manera objetiva e independiente, de manera que, pensemos en la mejor opción para resolver nuestro propio problema y no el de todos los demás (o el de alguien más en particular) entonces podamos tener mejores resultados. La NASA tomó esta filosofía después de los desastres del columbia y el challenger, no veo porque nosotros como ingenieros en software no podamos aplicarla también… de vez en cuando.
Saludos.
Es curioso, hace unos dias reflexionaba lo mismo al estar esperando por la actualizacion de una aplicacion en linux, antes descargabamos el codigo, se compilaba e instalaba; hoy en dia, hasta para instalar software nos hemos vuelto dependientes de terceros. En fin, hay que regresar a los origenes!
Buen articulo, saludos!!