Rankia España
Acceder
¿Nos visitas desde USA? Entra a tu página Rankia.us.
Blog Cambiando el mundo
Discusión de problemas y soluciones de actualidad económica mundial

Problemas de creencias en el diseño de software: Fundamentalismo informático

Igual que en economía, matemática, a veces hay ideas interesantes que pueden ayudar a resolver ciertos problemas bajo ciertas circunstancias. Pero la fascinación por la novedad con el tiempo crea formas retorcidas de extremismo ideológico, que no es otra cosa que mera creencia laica, una especie de fundamentalismo laico que pasa inadvertido porque todos tratan de mirar el fundamentalismo religioso.

A la hora de diseñar software, aunque sepas cómo optimizar tu código en VBA, te dirán que aprendas a programar "un lenguaje de verdad".  Si se trata de buscar mercado para buscar empleo, puedes seguir consejos para adaptarte a las tendencias de moda, pero si ya sabes programar en VBA, y puedes resolver tus problemas cotidianos con ello, sin tener que responder a un cliente o jefe que te pide código en determinado lenguaje, realmente está bien.

Para comprender el problema de creencias, tenemos que comprender la historia.

Antecedentes

Para comprender las creencias, tenemos que remitirnos a la historia de la programación. En un inicio existía el ensamblador, que es un lenguaje dificilísimo que toma muchísimos pasos para realizar la más básica de las tareas, y que traduce instrucciones al lenguaje máquina, que es el lenguaje que usa la computadora para efectuar tareas.  En algún momento alguien pensó en hacer la programación más fácil y escribió un compilador que tradujera código de un lenguaje más entendible a los lectores, y empiezan a surgir lenguajes relativamente más amigables. Y a partir de allí empieza la idea de crear lenguajes "de alto nivel", siendo que el ensamblador es de bajo nivel, y auqnue permite interactuar más directamente con la máquina, es dificil y largo escribir código.

Uno de estos lenguajes de alto nivel se llamó Fortran (abreviatura de Formula Translator) que permitía escribir código más entendible.  Del Fortran surge el lenguaje BASIC y luego sus futuras variaciones. Una variante muy popular fue GWBASIC para MS-DOS. El GWBASIC tenía un detalle horrible, pues podías lanzar la ejecución de vuelta a cualquier punto del programa con un comando llamado Goto, lo que dificultaba mucho leer el código y entenderlo, porque creaba una especie de tela de araña imposible de depurar si el programador era desordenado.

Entonces surgen lenguajes que empiezan a usar programación estructurada, donde puedes ramificar o repetir, pero ya no hacer saltos a todas partes del programa.  Con el advenimiento de Windows viene Visual Basic, que permite programar código para ambiente gráfico y usa programación estructurada. Pero como Microsoft siempre ha tenido la mala costumbre de ser relativamente ineficiente, el Visual Basic ha quedado relegado porque hay tareas que se pueden volver muy intensivas e ineficientes en uso de recursos cuando trabajas cantidades masivas.  Incluso con herramientas separadas de Visual Basic, como Access, podías tener problemas para correr código debido a la inconsistencia en la versión instalada de Access y eso era un dolor de cabeza, aparte del problema de que Access no era capaz de manejar bases de datos muy grandes.  Allí es donde vino Oracle, que desarrolló herramientas para trabajar cantidades masivas de datos para hacer Business Intelligence.  Por supuesto Oracle ha mantenido el conocimiento muy escondido, de modo que hasta tenías que tomar cursos carísimos para aprender a manejar Oracle, lo cual en un tiempo pasado fue algo que traía dinero a Oracle y a los que se certificaran.  Pero esto era el producto de la ausencia de competencia.

Y así, Visual Basic echó fama y se fue a dormir, igual que Microsoft.  Quedó con la mala fama de ser un producto secundario para programación por parte de aficionados, pero no útil para trabajos serios.  

Sin embargo un hecho que no se ha divulgado mucho es que si usas Windows, probablemente tendrás Excel y eso permite que programes en VBA (Visual Basic for Aplications) que es un kit básico de comandos en Visual Basic, que combinas con objetos de las aplicaciones de Office para crear programas (que la gente suele llamar macros).  Cada vez hay más y más herramientas que expanden el poder de Excel VBA para automatizar usando Twebst o Selenium o SAP RFC scripting o SAP GUI scripting, etc. Y tienes Power Query, PowerPivot and Power BI, que al combinarse con Sharepoint para Office 360 permite automatizar la elaboración de informes que se actualizan prácticamente solos, necesitando solamente de una pieza de código en VBA.  

Para los que no están conscientes de esto, Microsoft es una empresa que se viene a menos y que sólo ha lanzado más y más refritos de un Windows que se ha quemado con algunos fiascos como Windows 8 para móviles y PCs, o el cada vez más inútil Internet Explorer.  Realmente no importa, eso no le va a quitar negocios a Microsoft.  El problema es que esas creencias populares te pueden engañar a tí.

Problemas filosóficos de la programación orientada a objetos

Con el advenimiento del uso de C++ en la industria de videojuegos, vino un problema muy particular.  Si ibas a programar un videojuego con muchos coches, o muchos enemigos, e ibas a programar inteligencia artificial para cada uno, usar procedimientos, con una serie de pasos, no resultaba muy práctico.  Era mejor imaginar que el coche es un objeto, con características (propiedades) como color, modelo, estado de las llandas, potencia del motor, ubicación dentro de la pista, etc, y con capacidad de actuar (métodos) tales como acelerar, frenar, virar, etc.  Entonces se les ocurrió que se pudiese escribir sólo una pieza de código que serviría como los planos funcionales del coche (clase) y al ejecutar el programa se crearían los coches en memoria (instancias de una clase, objetos), de modo que con una sola pieza de código (clase) pudieses manejar múltiples coches (instancias de la clase).

A partir de allí empezaron a imaginar que todo en el mundo digital era un objeto con características (propiedades) y acciones (métodos) y situaciones que desencadenan acciones (eventos), y empiezan a inventar la teoría para su manejo, tales como encapsulamiento, herencia, y otros conceptos.

Entonces tienes Windows como un objeto que contiene un objeto llamado aplicación, que a su vez contiene otros objetos, y así es como operan las macros, que no es cotra cosa que uso de objetos.

¿Qué ocurre entonces con el BASIC que era un lenguaje procedimental y no basado en objetos?  ¿Qué ocurre con VBA que se deriva del Visual Basic y a su vez viene del BASIC?  Tienes un dilema.  ¿Usas programación orientada a objetos (Object Oriented Programming, OOP) o usas procedimientos?

Para responder esta pregunta hay que usar el pensamiento crítico, porque igual que en economía ya hemos ido encontrando inconsistencias y problemas con las ideologías, así en programación también lo encuentras.  También encuentras modas ideológicas entre programadores, y encuentras programadores pensantes.

¿Cuándo no usar objetos?

En un principio sólo había datos (contenidos en variables) y procedimientos (acciones).  Definías las variables y ejecutabas acciones.  Pero con el tiempo los datos necesitaban ser agrupados en estructuras de datos en memoria, y luego las acciones necesitaron ser agrupadas también junto con los datos, y había que detectar la ocurrencia de eventos que desencadenaban acciones. Y así surgen los objetos.  Eso es muy útil pàra un videojuego de coches.  Datos y acciones agrupados en entes independientes, coches virtuales que pueden tener "vida propia" en lugar de tener una aplicación central que maneje sus datos y efectúe acciones.

Al crear objetos estás tomando datos, los agrupas, y luego le asignas responsabilidades.  Los datos ocupan espacio en memoria pero se usan una y otra vez, las acciones ocupan tiempo de procesamiento y que se repiten mucho, y hay eventos que desencadenan acciones (como por ejemplo el choque de coches, cuando el usuario oprime un pedal, etc).  Pero hay situaciones donde no es necesario agrupar.

Imagina que solamente quieres descargar un archivo, agregar unos pocos datos, y luego volver a colgar el archivo.  Vas a efectuar tres tareas que no van a estar repitiéndose una y otra vez, sólo una vez.  El programador que usa OOP pensará que debe crear una clase y agregar las acciones.  ¿Para qué ocupar un espacio en memoria para todo un objeto y sus datos, si solamente necesitas usar unos pocos datos y efectuar unas pocas tareas?

Es que en este caso el objeto que tiene datos y que tiene acciones es el usuario mismo, y resulta absurdo crear un objeto emisario del usuario, que es como crear un avatar de usuario en memoria.  El usuario sólo necesita efectuar una tarea y ya, no gastar tiempo creando objetos y clases, para decir lo que se podría decir de manera simple:  Verbo y parámetros de la acción.  Es como si tuvieras un empleado y le das una orden. Usar OOP es como decirle al jefe, lléname este formulario con este formato, mucha burocracia para algo simple.

No es necesario usar objetos cuando los datos solo deben ser datos sueltos, y los pasos deben ser pasos sueltos.

Problema de jerarquías con herencias

También vas a tener problemas si hay algo que rompa la jerarquía.  Los objetos se agrupan en jerarquías, una especie de árbol jerárquico o genealógico.  Si tienes relaciones entre objetos en ramas distintas y en distintos niveles, empiezas a tener problemas.  Habrías imaginado que por tener objetos puedes tener la flexibilidad de conectar cualquier objeto con otro objeto, pero así no funciona.  Este arbol se crea a partir de la "herencia" en el diseño de objetos, presuntamente para facilitar reutilización y extensibilidad.  Pero al final la estructura de árbol es rígida porque dificulta conectar ramas en distintos niveles.

Luego de construir to árbol de jerarquías y haber gastado mucho tiempo diseñando objetos y herencias, te encuentras con que tienes que rediseñar todo y empezar de cero.

La herencia permite heredar acciones de sus padres.  Definiste un objeto genérico llamado "ente".  Si definiste un objeto "humano" como derivado de ente, este tendrá atributos y funciones de ente.  Puedes crear objetos derivados de humano llamados "hombre" y "mujer" que tendrá atributos y funciones humanas, como piernas para caminar y capacidad de pensar.  Puedes crear objetos "José" y "María" que son derivados de hombre y mujer.  Puedes crear un objeto llamado "coche" que es un derivado de ente.  El coche tendrá ruedas, partes metálicas, y partes de repuesto, y compartimientos de carga.  Se te ocurrió que si juntas partes metálicas, repuestos y capacidad de carga con características de pensamiento y extremidades de ser humano, puedes obtener un "robot" que es una combinación que obtiene las mejores características de coche y humano. Pero no puedes heredar caracteristicas de humano en tu coche, de modo que tendrías que copiar el código de humano en coche, o crear otra rama llamada robot que combine ambos.  O podrías querer fusionar coche y humano en una sola categoría y derivar robot y humano y coche de ese objeto.  Entonces, o reescribes el código, o duplicas código, lo cual destruye las ventajas que inicialmente creías tener al usar OOP. 

Y eso hace que la herencia te cree problemas que pretendías evitar en cualquier forma de programación.  Y eso que solo tenemos un arbol con dos ramas.  Imagina un árbol de 250 ramas, con 35 niveles en el árbol genealógico, donde 40 objetos de distintas ramas deben compartir características.  El resultado será un código spaghetti.

Hay maneras equivocadas de heredar, y eso hace que tengas un mal diseño.  Hay muchas malas prácticas que además de crear un spaghetti, te crea un adefesio.  Es algo así como el comando Goto que tenías en BASIC.  En ese sentido OOP es tan malo como programar en BASIC, pues puedes terminar teniendo un mamarracho de diseño que destruye la flexibilidad.  En BASIC debes tener el cuidado de no usar Goto, en OOP debes evitar malas prácticas de diseño.  En Basic puedes ver una mala programación si ves un Goto, pero no es tan fácil encontrar malos diseños con OOP.

Lo peor es que el fundamentalismo hace que si criticas OOP, ves llover las críticas hacia tí.  BASIC es tan amateur como OOP.  Pero programar OOP te hace ser idolatrado y programar en BASIC te hace paria.

La máquina que vende refrescos

Un ejemplo de la inutilidad de los objetos es la máquina que vende refrescos.  Es una máquina que prácticamente no necesita casi nada de memoria.  Imagina que existen monedas de 5, 10, 20 y 25 centavos.  La máquina tiene definidos estados para 0, 5, 10, 15, 20 y 25 centavos (representados como estados 0,1,2,3,4,5).  El usuario empieza a meter monedas, la máquina identifica el tamaño de la moneda y define cuantos estados saltar hacia adelante.  Si estaba en 0, e insertas una moneda de 20 centavos, salta 4 estados desde el 0 hasta el estado que representa 20 centavos, y almacena el estado número 4 en memoria.  Eso da el mismo resultado que meter 4 monedas de 5 centavos, donde cada moneda lanza al siguiente estado.  Si el estado se pasa de 5, entonces devuelve todo el dinero y vuelve la cuenta a 0.  En este tipo de proceso no necesitas procesos complicados, y cuando mucho vas a requerir 3 bits de memoria o equivalente en mecanismos mecánicos.  La máquina no necesita recordar si llegó a 20 centavos con moneda de 5 o de 20. Sólo necesita almacenar un estado, y efectuar una acción cuando la persona inserta la moneda.  No se necesita agrupar datos y acciones, aunque tienes un aparato que podría considerarse como un objeto.  Sería ridíciulo diseñar un artefacto mecánico que cree objetos con engranajes para agrupar datos y acciones, para simplemente vender refrescos.

Sólo necesitas el equivalente de 3 bits para almacenar un estado, y una serie de pasos que un aparato mecánico puede realizar sin necesidad de una computadora.  Por 3 bits no vale la pena crear un objeto.

La programación funcional

Existe otra situación en que realmente no necesitas definir datos en memoria (no necesitas declara nada), sólo procesos.  Imagina que vas a sumar los números desde 1 hasta un número x cualquiera.  Defines una función que recibe el número x.  Usas programación funcional, una donde la función efectúa todo el trabajo sin monitorear estados, como en la máquina de refrescos.

Sumar(x) = Si x es 1 o mayor, entonces Resultado = Resultado + Sumar(x-1).

Resultado es el valor que la función retorna, y x es un parámtro que el usuario da, de modo que no es necesario definir ninguno de los dos en memoria. La función recibirá el valor inicial de x y empezará a llamarse a sí misma de manera recurrente hasta que se obtiene el valor final de 1.  No fue necesario definir clases, ni siquiera declarar variables.  Sin variables, no es necesario crear un objeto.

Si bien la programación funcional es muy eficiente en uso de memoria, tiene su capacidad limitada por el tamaño de la pila (stack) que limita la cantidad de llamados que la función puede hacer a sí misma. 

Si creas un objeto para almacenar colección de números de 1 hasta n, y un método que suma el objeto actual y el anterior, llenarías la memoria con datos inútiles, ineficiencia pura.  Y allí es donde un semieficiente ciclo For-Next termina siendo un balance entre el ineficiente OOP y la eficiente pero limitada programación funcional.  No hay respuestas óptimas acerca de qué es mejor.

También la programación funcional tiene sus fundamentalistas.

La ideología de Agile para desarrollo de software

Si miras Wikipedia en lo relativo a "Agile software development" verás un buen concepto con una implementación terrible, porque al ver todos los libros y tratados sobre el tema, encontrarás que terminan complicando algo que es simple. Miras cómo los libros sobre el tema hacen lo mismo que los brujos, crear miedo en la gente, y luego empezar a dar órdenes como gurús.

El experimentado programador Dave Thomas, usa el pensamiento crítico y nos resume la aplicación práctica del concepto de Agile como:

¿Qué hacer?
1.Determina adonde estás
2.Toma un pequeño paso hacia tu meta
3.Ajusta tu comprensión basado en lo aprendido
4.Repite

¿Cómo hacerlo?
Cuando te encuentres con dos o más alternativas, que entregan más o menos lo mismo, toma la ruta que hace que los futuros cambios sean más fáciles.

Una vez que has tomado lo que Thomas nos dice, que es en realidad algo muy simple, no necestas sumergirte en los tratados que intentan desarrollar metodologías que resultan muy imprácticas cuando trabajas con proyectos grandes y muchas personas.  Es que pasaron de un concepto bueno a una metodología que carece de agilidad.  Entonces iterativo, evolucionario, deja de serlo, porque ya te petrificaron el cerebro con metodologías que no evolucionan, ni son iterativas.

Agile vende mucho a pesar de que al final, al tratar de desglosar e interpretar lo que dice Thomas, se vuelve algo que no itera y no evoluciona.  Agile vende porque es parte de la industria del miedo.  La gente compra cosas relativas a Agile, porque le meten miedo a lo que puede resultar de no usarlo.

Pensamiento crítico

Hay muchas situaciones donde resulta ridículo usar OOP, porque la idea es acudir a la técnica que haga más simple el programa, porque de otro modo, al depurar otro programador, o el mismo programador, se puede perder en la complejidad para un problema muy simple.  No hay que hacer complicado lo que es simple.

Si creías que en programación todo estaba inventado, o que debías hacerle caso al libro o al profesor, o al experto, y empezaste a apasionarte con las sectas de programación, empezarás a comprender que el mismo problema de fundamentalismo que suele atribuirse a la religión, existe en ámbitos tan insólitos como la programación.  Y como el fundamentalismo se basa en la pereza mental, en crear "zonas de no pensar" donde unos controlan a otros porque les resulta un negocio, comprenderás que las creencias no son equivalentes a religión, y que no es de la religión de la que tienes que cuidarte, sino de la ausencia de pensamiento crítico.

Es que si fuera un problema de religión, no habría fundamentalismos en otras áreas fuera de la religión.  Por supuesto, esto no es lo que los antirreligiosos quieren.  Pero es que el pensamiento crítico hace que seamos escépticos no sólo hacia la religión, o hacia otros fundamentalismos laicos.  

Resulta ridículo que haya fundamentalismos en algo tan técnico como la programación.  Programar es acerca de encontrar formas fáciles de solucionar problemas.  Los fundamentalismos laicos, propios de la idiosincrasia occidental, sólo nos vienen a complicar las soluciones, y hacernos perder tiempo.

¿Necesitas OOP?  Perfecto. Si te hace fácil la vida, bien. ¿Necesitas Agile?  Excelente, úsalo. Pero cuando recibimos la oleada de fundamentalistas que se salieron de la religión para ingresar al ámbito laico, empezamos a sentirnos aprisionados en temas ridículos y disputas absurdas que nos hacen la vida dificil.

¿Sabes por qué sigo usando VBA?  Porque casi no he necesitado diseñar objetos, pero eso no significa que no sepa cómo hacerlo.  Cuando los necesite, los usaré.  Cuando necesite otro lenguaje, lo usaré.  Lo que me gusta de VBA es que es una mezcla inteligible y simple de inglés y álgebra.  El pensamiento crítico ha hecho que encontrara en esa forma procedimiental de trabajar VBA, algo realmente práctico.

Esa forma procedimiental deja datos como datos, y acciones como acciones.  Y parece, dentro de mi ámbito de necesidades, suficiente para cubrir mis necesidades.  Quizás si un día voy a programar videojuegos, miraré a OOP con otros ojos, pero en la actualidad no me parece tan necesario para mis necesidades personales.

El pensamiento crítico es el pensar científico, y sirve tanto para cuestionar a religiosos, como a no religiosos.  El dogmatismo, fundamentalismo, y todas las cosas que solemos cuestionar a la religión, no son de dominio exclusivo de la religión.  George Soros habla de tres tipos de fundamentalismo en los EUA: Religioso, político y de mercado (fundamentalismo financiero).  Yo quiero agregar otro más, fundamentalismo informático.

Autor del blog


Este sitio web usa cookies para analizar la navegación del usuario. Política de cookies.
Cerrar