Lenguajes & Paradigmas

Desarrollo & Construcción de Software

Programación Orientada a Objetos

Paradigmas & Modelos de Abstracción

Javier Vélez Nov 2023 25 mins

Introducción

Tendrían que pasar dos largas décadas y varios paradigmas de programación - primero la programación estructurada y su variante modular y más tarde la programación funcional - para darnos cuenta, dentro de la comunidad del ingeniería del software, que algo no funcionaba. Si bien, desde un punto de vista exclusivamente académico, toda respuesta a los problemas de construcción de soluciones digitales parecía tener su espacio de aceptación, cuando estos modelos se pusieron en práctica en el más crudo escenario de las organizaciones empresariales, todos empezaron a mostrar sus fisuras y debilidades.

Corrían los principios de los años 70, y a este hecho dió en llamársele por aquella fecha la crisis de la ingeniería del software. La reflexión formal fue la de advertir que, contrariamente a lo que pudiera haber parecido al principio, no era tan buena idea basar las estrategias de diseño y construcción de software en poner foco de atención en la colección de tareas o procesos a los que atendía el problema bajo análisis. Se estaba rápidamente constatando que, si había algo fuertemente sometido a constante cambio dentro de un proyecto de desarrollo de software, eso era precisamente las tareas y procesos de dicho problema.

Parecía mucho más conveniente, poner foco de atención, sobre todo durante las fases iniciales de construcción, en la materialización de las entidades de datos con las que operaba un problema. Más allá de saber cómo se operaba en cierto dominio de negocio, interesaba antes saber qué entidades entraban a participar en dicho dominio. Había dejado de ser importante centrarse en preguntar por los cómos para centrarse en preguntar por los qués.

Objetivos

Y de esta manera, y casi sin darnos cuenta, habíamos llegado a los 90, cuando un nuevo paradigma, que como acabamos de explicar no lo era tanto dentro de la academia, cogió momento de aceptación universal. El mundo, no era una realidad cuajada de procedimientos o funciones operacionales. El mundo, cada realidad susceptible de ser digitalizada, era una realidad cuajada de entidades de datos. La era de los verbos estaba perdiendo fuerza y el reinado de los sustantivos se estaba estableciendo sin discusión. Los objetos serían la forma de materializar esa nueva concepción del mundo. Y este artificio mental ayudaría a poner foco en una suerte de puntos de atención que se reconocerían como los principales objetivos del paradigma.

  • Estabilidad. Centrar los esfuerzos de diseño y construcción de software en la identificación y creación de las categorías de objetos que forman parte del problema, permitiría que los procesos de desarrollo ganaran tremendamente en estabilidad. Como afirmábamos anteriormente, las abstracciones de datos son activos arquitectónicos mucho más estables durante toda la vida del proyecto que la colección de procesos que atraviesan dichas abstracciones.

  • Reutilización. Igualmente, basar el diseño de software en el uso masivo de abstracciones de datos expresadas en forma de objetos convenientemente categorizados, permitiría establecer, nítida y claramente, los espacios de reutilización potencial de cada tipo de objeto en el marco de la arquitectura. Esta suerte de encapsulación por abstracción, convertiría a los objetos en entidades autónomas capaces de ser reubicados en distintos contextos arquitectónicos de uso.

  • Composición. El diseño de objetos a través de la definición formal y computable de un perfil contractual basado en métodos y propiedades ayudaría a establecer claramente la morfología de cada entidad dentro de la arquitectura. A través de esta definición, quedarían claramente establecidas las formas posibles de conexión compositiva entre objetos, y de esta manera todo razonamiento relativo a la construcción compositiva podría expresarse en términos exclusivamente de perfiles contractuales y no a los comportamientos particulares de los objetos.

  • Extensión. Dado que cada objeto, dentro del marco de una solución, se exponía en forma de un perfil contractual, los límites fronterizos de las arquitecturas diseñadas en base al paradigma de la orientación a objetos encontrarían puntos de continuidad funcional a partir de la conexión compositiva con nuevas entidades construidas para dar soporte a la misma. De acuerdo a esta idea, toda arquitectura estaría cerrada a la funcionalidad y a la misma vez abierta a la extensión. Esta idea es tan relevante dentro de la orientación a objetos que se convertiría de hecho en uno de los principios de diseño fundacionales que discutiremos más adelante.

  • Adaptación. Finalmente, el diseño orientado a objetos debería permitir la creación de estirpes polimórficas de abstracciones donde diferentes variantes de objetos pudieran mostrar comportamientos divergentes a la vez que respetarán un mismo perfil contractual. Este hecho sería la base para permitir toda suerte de adaptaciones por conjugación sustitutiva de las distintas variables que morfológicamente encajaran en determinado locus dentro de la arquitectura. También este apetito daría lugar a un principio central de la orientación a objetos.

La nueva propuesta conceptual de desarrollo de software que trajo este paradigma estaba claramente alineada con los puntos de dolor identificados durante la crisis del software de los 70. Sin embargo, y para ser justos, hemos de señalar que muchas de las ideas que esta nueva aproximación aportó provenían, en realidad, de las lecciones que se habían aprendido en la comunidad durante los últimos 20 años, especialmente, aquellas surgidas en el seno de la programación estructurada y en especial del diseño modular de programas.

Principios

La colección de principios de diseño vinculados al paradigma de programación orientada objetos fue durante muchos años un área de investigación muy fecunda. Fueron muchos los autores que establecieron sus ideas en torno a cuáles deberían ser los vectores directrices para caracterizar esta nueva forma de construir software. Pero tal vez, la consolidación más culturalmente aceptada dentro de este ámbito, corresponde al compendio que Robert C. Martín popularizó en forma de las siglas SOLID, por sus nombres en inglés.

Personalmente, se me antoja pensar que esta enumeración de principios no es ni la más adecuada, ni la más completa ni tal vez la más descriptiva para hacerle justicia al paradigma. Sin embargo, la vida es, frecuentemente, una cuestión de imagen y personalmente quiero quedarme con la idea de que el acrónimo elegido describe brillantemente la característica esencial de esta aproximación de desarrollo de software.

  • Principio de Responsabilidad Única. El principio de responsabilidad única establece que en una arquitectura de objetos, todo artefacto debe cubrir una única responsabilidad, o por decir mejor, debe existir siempre una única razón para el cambio evolutivo dentro de cada tipo de objetos. Como ya hemos comentado, el soporte evolutivo en este paradigma se articula en base a la creación de variantes polimórficas. Si, para un tipo de objetos, estableciéramos diferentes líneas simultaneas de criterio evolutivo, entraríamos en conflicto al intentar expresar todas ellas mediante una sola estirpe polimórfica.

  • Principio Abierto Cerrado. Como explicábamos anteriormente, el principio abierto cerrado establece que todo software orientado a objetos debe estar funcionalmente preparado para operar correctamente pero, a su vez, debe estar abierto a posibles extensiones futuras. La manera de articular esto en el marco de la orientación a objetos, pasa por crear diferentes variantes polimórficas que, mostrando comportamientos divergentes, respetan un mismo perfil contractual de métodos y propiedades. El sistema se encuentra funcionalmente cerrado con las variantes existentes y a la vez abierto a la posibilidad de incluir nuevas variantes de manera no invasiva dentro de la arquitectura.

  • Principio de Sustitución Liskoviana. En alineamiento con la idea de abierto cerrado anterior, este principio establece que el diseño dentro de las arquitecturas orientadas a objetos debe centrarse en la definición estratégica de puntos de extensión polimórfica que permitan realizar sustituciones discrecionales entre variantes de objetos morfológicamente equivalente y contractualmente compatibles con el locus de colaboración arquitectónica donde se produce el remplazo. El principio anterior vehiculaba la capacidad de las arquitecturas orientadas a objetos para su extensión, este principio se centra en ofrecer comportamientos adaptativos por sustitución.

  • Principio de Segregación de Interfaces. Con miras a la reutilización de código, el principio de segregación de interfaces promueve la idea de que en toda abstracción participante en una arquitectura, el perfil de contrato debe establecerse a través de la realización de diferentes interfaces ortogonales previamente definidos. De una manera metafórica podemos considerar que esto equivale a decir que cada tipo de objetos dentro de este paradigm es una realidad poliédrica donde cada plano de comportamiento se define en una interfaz diferente. Al posicionar un objetos dentro de un locus de colaboración arquitectónica forzamos la exposición exclusiva del perfil que demande dicha colaboración.

  • Principio de Inversión de Dependencias. Finalmente, el principio de inversión de dependencias establece que. en toda solución orientada a objetos, cualquier colaboración entre los mismos debe articularse a un mismo nivel de abstracción y nunca desde niveles de abstracción dispares. En este sentido, los algoritmos se expresan siempre como colaboraciones abstractas que luego se concretan en términos de sustituciones liskovianas con las diferentes variantes que encontremos implementadas en el espacio de la solución, tal como comentábamos anteriormente.

Desconozco si el autor fue buscando los principios antes que las siglas o más bien al revés. Pero lo cierto es que decir que la orientación a objetos es esencialmente sólida para bien o para mal es muy acertado. Constataríamos este hecho algunos años después, cuando comprobáramos que existen otras formas mucho más flexibles y plásticas de crear software pero a la vez más inestables y de riesgo. Esto abre un nuevo camino apasionante del que ya hablaremos más de esto en un próximo artículo.

Mecanismos

El primer lenguaje de soporte a la orientación a objetos data de finales de los 60 con la aparición de Simula. Pero tuvimos que esperar algo más de una década para ver nacer y desarrollarse a SmallTalk, que hoy por hoy es reconocido como el ejemplo por antonomasia del paradigma. Al menos, esta realidad se cuenta así en la academia porque lo cierto es que en el mundo empresarial, la orientación a objetos no estuvo en pleno despliegue hasta que a mediados de los 90 Java hiciera su aparición en escena de la mano de la hoy desaparecida Sun Microsystems.

Algunos años después, al filo del nuevo siglo, Microsoft querría poner su pica en Flandes con el diseño de C# una versión sintácticamente mejorada - aunque fuertemente inspirada - en las bases que ya había sentado Java durante casi 10 años de historia. Después de eso, en el ámbito de las arquitecturas de front, la cultura de la orientación a objetos se evangelizaría, primero a través de Dart y luego a través de TypeScript, que fueron base de importantes marcos de desarrollo ideados por el gigante Google.

El caso es que sobre la base de estos lenguajes aprendimos a reconocer los mecanismos fundamentales de la orientación a objetos. En este paradigma, todos los programas consisten en colecciones de objetos que, en tiempo de diseño se definen a través de clases e interfaces. Asi construidos, los objetos quedaban categorizados de acuerdo a las clases a la que pertenecían y los interfaces que realizaban lo que les conferiría el perfil contractual característico para habilitar su participación en diferentes contextos arquitectónicos de uso durante su ejecución.

A diferencia de lo que ocurriera en aproximaciones anteriores, donde la ejecución tenia un fuerte enfoque jerarquizado, en la orientación a objetos, el relato de la ejecución se expresaba en términos de un diálogo fluido entre objetos basado en el intercambio de mensajes de invocación. Este hecho hacia pensar en la ejecución como una actividad más horizontal que vertical. Un proceso colaborativo entre partes - los objetos - donde cada entidad jugaba un papel responsable precisado en base a su perfil contractual. El diseño residía en precisar, sobre esa horizontal, cómo se distribuía entre los objeto en participación, el espacio de responsabilidades, de manera que el sistema final presentara el comportamiento colaborativo deseado.

Sobre la base de ese modelo dialógico de ejecución, las ideas fueron germinándose y asentándose con una fuerte atención en los vectores de empuje de los principios de diseño. Y este esfuerzo de creación llevo casi la friolera de 20 años, desde la primera idea de delegación hasta las últimas aportaciones de soporte basadas en la idea de genericidad. Podemos resumir en los siguientes los principales mecanismos del lenguaje.

  • Delegación. La delegación es, si se quiere, el mecanismo germinal de la orientación a objetos. En términos simples, se trata de un mecanismo que permite a un objeto enviar un mensaje a otro objeto para realizar una tarea en su nombre. El envío de este mensaje se articula por medio de la invocación de un método miembro del objeto receptor, y que está descrito en la clase a la que pertenece dicho objeto. Pero esto soporta la idea de que, algunos objetos tengan la facultad de delegar ciertas tareas para que las realice otro objeto. Esto se realiza en virtud de la estrategia de división de responsabilidades que se haya ideado durante el diseño de la solución.

  • Encapsulación. La protección de la información, es la práctica generalizada de no basar los usos de una abstracción los detalles particulares de su implementación interna. En el marco de la orientación a objetos, consiste en el proceso de ocultar los detalles internos de un objeto y proporcionar una interfaz pública de métodos y propiedades que opera como contrato formal para interactuar con el objeto. Los lenguajes de soporte al paradigma proporcionan la encapsulación como mecanismo para forzar por código el cumplimiento de esta idea.

  • Herencia. La herencia es un mecanismo del lenguaje que permite a una clase adquirir todos los rasgos estructurales y de comportamiento de otra clase. La aplicación de este mecanismo establece una relación de dependencia entre las clases implicadas de manera que la clase de la que se hereda el comportamiento se llama clase padre o clase base y la clase que lo hereda se refiere con el término de clase hija o derivada. El uso de la herencia puede tener dos usos pragmáticos complementarios. Por un lado se utiliza herencia para crear nuevas variantes especializadas sobre la base de la clase padre y por otro se habilita la posibilidad de crear varias variantes hijas con rasgos de comportamiento diferentes entre sí.

  • Polimorfismo. Como acabamos de explicar, es principalmente a partir del mecanismo de la herencia que se consiguen crear clases con una misma estructura de contrato pero comportamientos divergentes. Al mecanismo que permite al lenguaje reconocer la homogeneidad contractual de ambas abstracciones y considerarlas como variantes mutuamente sustituibles se le conoce con el nombre de polimorfismo entre clases. Por extensión de esta idea, aplicada sobre diferentes elementos característicos de un programa puede hablarse de polimorfismo paramétrico entre métodos miembro de una clase.

  • Ligadura Dinámica. La ligadura dinámica confiere un importante grado de dinamismo flexible en la orientación a objetos y fue un reto de desarrollo por parte de los ingenieros de lenguajes en el marco de la teoría de compiladores. En esencia, la ligadura dinámica es un mecanismo que permite a un objeto determinar en tiempo de ejecución qué método debe ser llamado, en lugar de determinarlo en tiempo de compilación. Esto significa que el método que se ejecuta depende del tipo de objeto en tiempo de ejecución, en lugar del tipo de objeto en tiempo de compilación.

  • Genericidad. Finalmente, la genericidad es un mecanismo que permite definir clases y métodos que pueden trabajar con diferentes tipos de datos. Esto significa que se puede escribir código que sea independiente del tipo de datos que se estén utilizando. El término utilizado recuerda a la idea de que podemos definir abstracciones de datos que no solamente sean un esfuerzo de generalización en términos conceptuales sino en relación a los tipos de base con los que opera. Este mecanismo fomenta la reutilización y evita la necesidad de duplicar una misma abstracción cuyo comportamiento solo se diferencia en base al tipo sobre el que opera.

Arquitecturas

La investigación sobre arquitecturas de software orientadas a objetos también ha sido un perímetro de actividad intensa y muy fructífero. Aunque pueden encontrarse muchas publicaciones de valor en la literatura sobre este tema, el que es considerado, sin lugar a dudas, el marco de referencia por excelencia es la colección Pattern-Oriented Software Architecture, que a fecha de hoy acumula 5 volúmenes. Sin el ánimo de entrar en comprometidas enumeraciones exhaustivas, sí podemos citar a los siguientes como ejemplos canónicos de modelos arquitectónicos de referencia basados en el uso de la orientación a objetos.

  • Arquitectura por Capas. Las arquitecturas en capas conforman un modelo de diseño arquitectónico que se enfoca en la separación de las diferentes funcionalidades del sistema en capas o niveles de operación. Estas capas se responsabilizan de tareas específicas y se comunican entre sí con los niveles adyacentes mediante interfaces bien definidas. Cada capa se construye sobre la capa inmediatamente inferior, que es responsable de proporcionar los servicios y la funcionalidad que ésta necesita. Este modelo fomenta la modularidad y facilita el mantenimiento correctivo y evolutivo.

  • Arquitectura Basada en Eventos. Las arquitecturas basadas en eventos constituyen un modelo arquitectónico que se enfoca en la detección de eventos que representan acontecimientos ambientales relevantes en el plano computable para actuar sobre ellos en tiempo real. En este modelo, el registro, la comunicación, el procesamiento y la permanencia de los eventos son la estructura central de la solución. La arquitectura basada en eventos se compone de productores y consumidores de eventos, donde el primero detecta los eventos y los representa como mensajes, y el segundo recibe la notificación de que ocurrió un evento y ejecuta la respuesta adecuada para el mismo. Este modelo arquitectónico fomenta el desacoplamiento el escalado reactivo aunque puede generar problemas de gobierno cuando crece la complejidad reactiva del problema.

  • Arquitectura de Microkernel. Las arquitecturas de microkernel son un modelo arquitectónico que permite crear aplicaciones extensibles en las que es posible agregar nueva funcionalidad mediante la adición de pequeños plugins que extienden la funcionalidad inicial del sistema. En una arquitectura de microkernel, las aplicaciones se dividen en dos tipos de artefactos complementarios. Por un lado, destaca el activo central o Kernel que es una pieza única dentro de la arquitectura. De otro, se integran los plugins que contribuyen al Kernel con capacidades especializadas. Este modelo arquitectónico está fuertemente inspirado en el principio de abierto cerrado que explicamos con anterioridad.

  • Arquitectura Cliente Servidor. En las arquitecturas cliente servidor se distingue un artefacto central llamado servidor que es el responsable de atender las peticiones de un conjunto potencialmente infinito de abstracciones cliente. La comunicación entre ambas partes se establece de acuerdo a un protocolo de colaboración entre objetos. El hecho de que este tipo de arquitecturas haya sido utilizado en el Marco de la computación distribuida para diseñar muchas soluciones dentro de los sistemas de redes no debe Confundirnos. Este es un modelo arquitectónico más que se desarrolla enteramente dentro del Marco de un único espacio de ejecución.

  • Arquitectura Maestro Esclavo. Las soluciones maestro esclavo constituyen un modelo de solución en el que una entidad central, conocido como entidad maestra, ejerce un papel de coordinación orquestal sobre la bae de una colección de agentes, conocidos como esclavos, que están especializados en la realización de ciertas tareas específicas. En este sentido, el maestro es responsable de asignar tareas a los esclavos y de coordinar su funcionamiento mientras que los esclavos son responsables de realizar las tareas asignadas por el maestro y de enviar los resultados de vuelta al maestro.

  • Arquitectura de Tuberías y Filtros. Las arquitecturas de tuberías son un modelo de solución que se utiliza para construir sistemas de procesamiento de datos. En este esquema, los datos se procesan en una serie de filtros dispuestos en cadena por medio del uso de tuberías. El hecho de hacer atravesar los datos por una arquitectura de filtros desencadena los efectos de procesamiento deseado sobre los datos. Sobre este modelo arquitectónico pueden distinguirse dos modos o estrategias de diseño complementarias. El el modo Pull el filtro en el extremo final de la cadena, que es conocido por el nombre de sumidero, va pidiendo datos bajo demanda al filtro inmediatamente anterior hasta llegar al primer filtro conectado directamente a los datos, que se conoce con el nombre de fuente. En el modo push, la operación es recíproca, de manera que es la fuente la que proactivamente empuja datos sobre la cadena de manera que cada filtro pasa los datos a su siguiente filtro en la cadena tras su procesamiento.

  • Arquitectura de Broker. Una arquitectura de Broker es un modelo de solución en el que los componentes de software se comunican entre sí a través de un intermediario llamado Broker. En este sentido, se distinguen dos tipos de componentes, productores y consumidores. Los productores son componentes encargados de generar datos que el Broker se encarga de enrutar hacia los consumidores adecuados para su procesamiento. En una arquitectura de brokerage, los productores y consumidores utilizan al Broker como elemento de intermediación desacoplada en la comunicación lo que permite una mayor flexibilidad y escalabilidad en la arquitectura. Además, en ocasiones, el Broker puede proporcionar servicios adicionales, de transformación, validación, filtro.

  • Arquitectura Punto a Punto. Si las arquitecturas de brokerage se caracterizaban por tener un elemento central de intermediación que realizaba tareas de enrutamiento de mensajes de origen a destino, en las arquitecturas punto a punto se proporciona un medio mediante el cual cada agente puede establecer una conexión directa con otro agente. En contraste con las soluciones cliente servidor donde hay un marcado carácter jerárquico entre los clientes y el servidor, en este tipo de arquitecturas, todos los agentes pueden adquirir un rol circunstancial de aprovisionadores o consumidores de información para alguno de sus pares. De todo lo anterior se deduce que la diferencia característica de esta aproximación con respecto a las anteriores estriba en el carácter descentralizado y distribuido de la colaboración entre artefactos.

Dentro de la enumeración anterior, pueden reconocerse algunas de las arquitecturas que fueron descritas en el paradigma de la programación funcional. Lejos de ser un error, este hecho pone de relieve una idea interesante cual es que, un determinado modelo arquitectónico puede, en ocasiones, encontrar su despliegue pragmático sobre la base de distintos paradigmas. Si bien el sustrato de base arquitectónico debe ser el mismo, es frecuente que su expresión paradigmática sea diferente e incluso ello pueda afectar a su alcance y orientación.

Patrones

Aunque hoy en día tenemos costumbre de hablar de patrones de diseño en el marco de muchas disciplinas, lo cierto es que fue en el contexto del paradigma de la orientación a objetos donde primero se empezó hablar de esta forma discursiva. Si bien ya existían formas válidas convencionales de describir un cuerpo de conocimiento, no fue hasta la llegada de Eric Gamma que propuso el uso de un modelo basado en patrones para describir el conocimiento relativo a las actividades de diseño de arquitecturas de software basadas en objetos, que hasta la fecha se entendían como una actividad artesanal de gran experiencia.

La idea del uso de catálogos de patrones para capturar cuerpos de conocimiento no es algo que se le deba originalmente a Eric. Un tal Christopher Alexander, referente del campo de la construcción de edificios arquitectónicos, había utilizado con anterioridad este modelo narrativo para explicar la forma de dar soluciones en el campo de la arquitectura física. Pero es de justicia reconocer que si no hubiera sido porque Eric tuvo el acierto de leer a Alexander en sus ratos libres tal vez hoy en día no estaríamos hablando dentro de la ingeniería del software de patrones de diseño.

Lamentablemente un estudio en profundidad acerca de cada uno de los 24 patrones que Gamma y sus colaboradores publicaron en el año 95 cae fuera del alcance de este artículo. Sin embargo si vale la pena enunciar cada uno de las tres familias en las que los patrones identificados por Gamma pudieron ser convenientemente clasificados.

  • Patrones Creacionales. Los patrones de diseño de esta categoría ofrecen diferentes estrategias relacionadas con los problemas relativos a la creación de objetos. Algunos ejemplos dentro de esta familia son el patrón de fábrica, el patrón de constructor y el patrón de prototipo.

  • Patrones Estructurales. Los patrones de diseño estructurales se centran ofrecer respuestas probadas para problemas recurrentes relativos sobre la composición y estructura de las clases y objetos. Algunos ejemplos son el patrón de adaptador, el patrón de puente y el patrón de decorador.

  • Patrones de Comportamiento. Por su parte, los patrones de la familia de comportamiento se centran en dar respuesta a problemas que se refieren a la interacción entre los objetos y la distribución de responsabilidades. Algunos ejemplos son el patrón de cadena de responsabilidad, el patrón de comando y el patrón de observador.

Con el tiempo algunos autores han reconocido nuevas familias de patrones que se han venido a sumar a este marco descriptivo. También se han incorporado patrones menores dentro de alguna de las tres categorías anteriores. Un buen trabajo en este sentido es toda la literatura que al respecto ha hecho Marc Grand. Sin embargo, hay que señalar, que el trabajo germinal que hizo Eric a este respecto todavía sigue siendo la fundamental base sólida de la forma de construir soluciones robustas y homogéneas basadas en el uso del paradigma de orientación a objetos.

Técnicas

El marco de la orientación a objetos es, sin lugar a dudas, el cuerpo teórico de construcción de soluciones de software más reglado y dirigido de todos los paradigmas de programación existentes. Como hemos analizado a largo de este artículo, tanto en el espacio de los principios de diseño como en el de los patrones y los modelos arquitectónicos de referencia, ha existido una fuerte y prolífica actividad investigadora que han modulado un espacio de operación maduro y sólido.

A diferencia de lo que ocurre con otras aproximaciones, la actividad cotidiana que realizan los desarrolladores cuando abordan procesos de codificación basados en la orientación objetos dan poco espacio a la creatividad estilística y a los modismos culturales. Desarrollar bien en orientación a objetos consiste en seguir y aplicar clara y disciplinariamente los principios y patrones de diseño oportunos para cada estereotipo de problema identificado.

Pero si bien todo lo anterior es cierto, no lo es menos que, existen una suerte de lenguajes de programación que si bien permiten en sentido estricto desarrollar soluciones basadas en la orientación a objetos no ofrecen ni mecanismos de soporte sólidos para ello ni conceptualización es de ejecución adecuadas. Es en estos contextos donde la creatividad del desarrollador debe jugar un papel importante porque está precisamente a sus espaldas convertida en disciplina de desarrollo todo lo que el lenguaje no ofrece como un mecanismo.

JavaScript es, tal vez, el mayor representante de esta corriente disruptiva de desarrollo que desde luego no deja indiferente a nadie. Si bien es imposible decir que este lenguaje respete en forma alguna los miembros estructurales de la orientación a objetos lo cierto es que el tiempo nos enseña que a los lenguajes hay que entenderlos primero para poder programar sobre ellos. Este es, sin lugar a dudas, un recorrido tan interesante que bien merece la pena dedicar toda una serie de artículos a este tema.

Conclusiones

Decir que el mundo es una realidad concebida por abstracciones de datos y que en torno a ellas debemos articular el conjunto de métodos y propiedades características que permiten operar con estas entidades hoy parece una reflexión trivial. Pero haciendo un poco de retrospectiva histórica no podemos por menos que asombrarnos de la capacidad imaginativa que tenían nuestros mayores cuando concibieron formas disruptivas de concebir los procesos de diseño y construcción de soluciones de software.

Hoy por hoy los procesos centrados en la definición de soluciones basadas en tareas y composiciones de operaciones funcionales parece haber cogido un nuevo impulso. De hecho la programación funcional parece estar más de moda que nunca y en cierto sentido está desbancando culturalmente al paradigma de orientación a objetos que sin lugar a dudas fue el baluarte fundamental de toda la profesión durante la friolera de más de 20 años.

En un artículo anterior, al hablar de la programación funcional, ya discutimos los posibles sospechosos culpables de esta realidad. Pero el buen experto debe reconocer que para los clavos están los martillos y para los tornillos los destornilladores. Más allá de llevarnos por preferencias culturales y modismos, los expertos de la profesión debemos forzarnos a hacer una reflexión no tendenciosa acerca de cuál es el mejor paradigma para desarrollar una solución particular. Soy consciente de que, en esta reflexión sosegada, las tendencias del mercado no ayudan para nada porque hay, quizás, demasiados intereses creados para poner todos los huevos en la misma cesta en cada momento determinado de la historia.

En cualquier caso, esta misma historia no nos dejará mentir. La orientación a objetos fue el gran salvavidas que puso punto y final a la crisis del software que venía haciendo agonizar a la comunidad hasta los años 70. Y aunque a los agilistas les moleste mucho reconocerlo, los procesos de desarrollo iterativo e incremental centrados en la revisitación sistemática de características debemos agradecérselos a los modelos metodológicos que nacieron en el seno de la orientación a objetos.

A lo largo de este artículo, hemos citado a muchos autores que han tenido un protagonismo preponderante en la construcción del paradigma. Sin embargo, sería injusto cerrar aquí sin citar a los dos grandes nombres que a mi juicio deben ser reconocidos como los padres de esta disciplina de construcción de software tal y como finalmente fue constituida. Por un lado reconocer el valor de la gran Barbara Liskov que describió el principio que lleva su nombre. Por otro citar al gran Beltran Meyer, que entre otras muchísimas aportaciones es padre del principio abierto cerrado, insignia mas característica, a mi entender, de la orientación a objetos.