"Antes de que un software sea reutilizable debería ser utilizable". Ralph Johnson (1994).
Modelar una aplicación computacional de manera que responda a una problemática concreta y que presente una solución viable es una forma de asegurarse de que el programa que se desarrolla tiene un valor agregado.
Frecuentemente se encuentran situaciones en la cotidianeidad que bien podrían tener un soporte mediante una aplicación móvil o un cliente en la nube que permita simplificar su complejidad y mejorar su eficiencia.
Como programador, se tiene una manera peculiar de ver el mundo, una que permite identificar estas situaciones, así como esas posibles aplicaciones. Esta visión es así, gracias a los diferentes paradigmas de programación.
Entenderlos permite que se tenga un criterio más amplio al momento de modelar una aplicación; una mayor comprensión de estos temas puede ayudar a producir programas con un más alto grado de utilidad, misma que pueda ser replicada y reutilizada en escenarios diferentes pero que guarden similitudes. Por ejemplo, identificar las necesidades informáticas de un negocio de abarrotes y así modelar una aplicación que ayude a diferentes negocios del mismo giro.
En este tema explorarás diferentes paradigmas de programación con diferentes enfoques y premisas.
Un paradigma es un ejemplo típico o patrón de algo según Wassberg (2020), y siguiendo está definición es posible agrupar los diferentes lenguajes de programación de acuerdo con la manera en que permiten resolver problemas computacionales.
Entender este concepto se vuelve relevante cuando se entiende que el código escrito variará significativamente como consecuencia del paradigma utilizado.
En esencia, un paradigma se expresa como una técnica o conjunto de técnicas de programación de acuerdo con que influyen directamente en el diseño del programa, así como en los diferentes componentes que este tendrá.
Existen diferentes paradigmas de programación que dan solución a un nicho distinto de problemas, como lo son: de programación paralela, de inteligencia artificial, funcional, entre otras; cada una con un objetivo y enfoque específico.
Programación estructurada
En los inicios de la programación las aplicaciones se realizaban en ensamblador, que es un lenguaje secuencial basado en mnemónicos de bajo nivel donde cada comando tiene una traducción directa en lenguaje máquina y representa operaciones simples como mover valores de una variable a otra, sumarlos, restarlos, asignarlos etcétera.
Los lenguajes ensambladores son específicos de cada procesador y usualmente no contienen estructuras repetitivas o selectivas y la organización del código suele ser más complicado, ya que algoritmos complejos se tienen que describir de manera lineal y las iteraciones y bifurcaciones se tienen que escribir también directamente. Todo esto es llevado a cabo mediante el concepto de GOTOs (del inglés, ir a) y la inclusión de etiquetas dentro del código lo que permite a este saltar de una a otra; esto provoca que las aplicaciones sean susceptibles a errores humanos, lo que dificulta su desarrollo y mantenimiento (Wassberg, 2020).
El paradigma de programación estructurada nació para dar solución a este problema, ya que permite escribir código más limpio y fácil de mantener. Este paradigma pertenece a una rama de la familia de paradigmas llamados programación imperativa y, como su nombre lo dice, el paradigma de programación estructurada se fundamenta en estructuras iterativas (while, for, etc.), de decisión (if, switch), entre otras.
Debido a que cada estructura es fácilmente reconocible, el código escrito bajo este paradigma es más fácil de leer. Además, se tiene un mayor control de este. Existe una gran variedad de lenguajes que fueron desarrollados bajo este paradigma como lo son C, Pascal y Basic, entre otros.
Programación modular
En esencia, la programación modular se puede considerar en cierta manera como un término intercambiable con programación estructurada, ya que ambas fundamentan su estilo. La programación modular tiene como principio la reutilización de códigos, de tal manera, que diferentes segmentos de códigos pueden ser escritos como módulos dentro del sistema y que pueden ser reutilizados en otra parte de este.
Una aplicación escrita bajo este paradigma busca abstraer partes concretas de un algoritmo o algoritmos mismos en porciones reutilizables dentro de procedimientos o funciones (según el lenguaje de programación), de manera que se optimice su escritura y mantenimiento.
De esta manera podemos ver que algunos lenguajes imperativos soportan también los conceptos de programación modular, ya que esta se diferencia principalmente por un estilo de la programación estructurada.
Programación orientada a objetos
El principio fundamental detrás de la programación orientada a objetos es el de modelar una aplicación de la misma manera en que los humanos vemos el mundo.
Las personas solemos realizar abstracciones en nuestra vida cotidiana agrupando cosas por su uso y utilidad. Las personas solemos realizar abstracciones en nuestra vida cotidiana agrupando cosas por su función, características, uso o utilidad, permitiéndonos referirnos a ellas de manera general y lograr un buen nivel de entendimiento.
De esta manera, cuando escribimos código bajo este paradigma podemos describir los elementos que forma parte del sistema que se está modelando utilizarlos dentro de nuestra aplicación. Por ejemplo, si vamos a realizar una aplicación que maneje el control de una tienda de abarrotes es posible identificar elementos tales como productos, clientes o vendedores, y describir de cada uno de ellos sus características peculiares, como lo son para unos su nombre, su precio, su cantidad en el inventario y, para la para los otros, su información de contacto.
Para realizar un sistema necesitamos conocer algunos detalles de los elementos que lo conforman, pero no todos y este principio forma parte fundamental del paradigma de programación orientado objetos, de tal manera que el proceso de abstracción nos lleva a identificar dichas características que son relevantes y aportan valor a la aplicación y deberán ser incluidas, y descartar por otro lado.
Para entender mejor este paradigma es necesario entender varios conceptos sobre los cuáles está fundamentado.
Primer concepto es el de clase. Una clase se podría considerar como una plantilla en la cual se plasman todas las características relevantes de un elemento que forma parte del sistema. Por ejemplo, si en nuestro sistema vamos a incluir a una persona podemos identificar en ella varias características, tales como color de ojos, color de cabello, nombre, edad, domicilio, etc. De la misma manera podemos describir varios de sus comportamientos, como lo son el hablar, pensar y correr, entre otros.
Figura 1. Representación de una clase Persona.
Sin embargo, muchas de estas características o datos no son relevantes dentro del sistema, por lo que podemos descartarlos. Mediante el proceso de abstracción es que se tomarán únicamente aquellos que sean que aporten valor al sistema, por ejemplo, nombre, domicilio, edad y otros más que nos permitan distinguir entre dos individuos dentro del sistema. Como se puede observar, este paradigma permite una modelación más orgánica de los datos y, por lo tanto, resulta especialmente útil en sistemas cuyo enfoque sea el manejo de información.
Figura 2. Representación de una clase Persona con características relevantes al sistema.
Los objetos son representaciones de las clases previamente descritas. A partir de una clase podemos tener múltiples objetos donde cada uno tenga valores distintivos para las características descritas, por ejemplo, al tener una clase llamada Persona, cuyas características son nombre, domicilio y edad, se puede tener un objeto, cuyo valor para el nombre sea el de Roberto, otro objeto que tenga el valor de Cecilia y así, sucesivamente.
Figura 3. Par de objetos generados a partir de clase Persona.
Asimismo, dentro de la clase tenemos el concepto de atributo que representa las características de los elementos que se están modelando y, por otro lado, los comportamientos que son aquellas acciones que este elemento puede realizar. Es importante destacar que dentro de una aplicación de software los comportamientos que más nos importan son aquellos dirigidos a modificar los datos del propio objeto. De esta manera, dentro del proceso de abstracción descartamos para la clase persona comportamientos tales como el de hablar, pensar, escribir, etc. Y se da preferencia a comportamientos como el de modificar nombre, obtener nombre, modificar edad, etcétera.
Dentro de la programación orientada a objetos podemos encontrar incluidos los conceptos de programación estructurada y programación modular, por lo que este paradigma ofrece una forma más completa para el desarrollo.
Estas y otras características han vuelto a este paradigma uno de los más populares en las últimas décadas. Una cantidad muy importante de aplicaciones han sido escritas bajo este paradigma y su dominio en el mercado sigue siendo indiscutible.
Uno de los lenguajes de programación más importantes en la actualidad que permite desarrollar aplicaciones siguiendo este paradigma es Java, que comenzó su popularidad desde los noventa y sigue siendo líder en el mercado de desarrollo de software.
Programación funcional
Como Mueller (2019) señala, la programación funcional se distingue de otros paradigmas en el uso de funciones matemáticas en lugar de declaraciones o statements para representar planteamientos.
Esto significa que, en lugar de enfocarse en redactar un conjunto concreto de pasos para resolver un problema, se declaran y usan funciones, permitiendo que el propio lenguaje se haga cargo de la manera en que estas operaciones se realizan. Es decir, su enfoque se centra más en plantear los resultados esperados.
En programación funcional no se da soporte al uso de estados; esto forma parte central de este paradigma, pues, aunque pierde la capacidad de hacer un seguimiento puntual de los valores adoptados durante la ejecución de un programa se gana una mayor predictibilidad. En lenguajes donde se consideran los estados, cada llamada de una función puede producir resultados muy variados e incluso inesperados, pues dependerán de los valores que se tengan en variables globales o en atributos de un objeto.
Las variables dentro de una función son inmutables y es esto lo que garantiza en múltiples llamadas a una función, logrando que la misma lista de argumentos tenga siempre el mismo resultado.
Por otro lado, el uso de estados genera también interdependencia de código. La programación funcional elimina esta interdependencia y crea con esto un entorno más flexible de desarrollo (Mueller, 2019).
En la actualidad se tienen lenguajes que hacen un uso puro de programación funcional, respetando todas las premisas que este plantea, pero también hay otros como Java que incorpora a un enfoque orientado a objetos elementos propios de la programación funcional mediante la inclusión de expresiones lambda, permitiendo así tomar lo mejor de cada paradigma e incorporarlo en una misma aplicación.
Los lenguajes de programación funcionales incluyen además otras características como las siguientes:
Los paradigmas de programación existen desde que existe la programación misma y es importante conocer su historia y evolución para sacar mayor provecho de sus características.
En la actualidad es muy común encontrar lenguajes de programación que combinan características de más de un paradigma, por lo que entenderlas se vuelve indispensable. Además, conocer diferentes paradigmas te dará una mayor comprensión y diferentes enfoques para la solución de los posibles problemas que te encuentres, ya que la popularidad de un paradigma o lenguaje de programación no define su potencial.
Recuerda que a mayor cantidad de herramientas que manejes, mejor será tu desempeño como profesional de la programación y muchas de estas, si no todas, tienen fundamento en los diferentes paradigmas de programación existentes, por lo que te será de gran utilidad el seguir aprendiendo sobre este tema.
Asegúrate de: