Portada del libro |
Este es mi punto de vista sobre las Tecnologías de la Información, Software y Pensamiento Ágil. Especialmente en lo que respecta a procesos y métodos, modelos y sistemas, marcos de trabajo y prácticas ágiles, experiencia en la industria, transformación organizacional, cultura, generación de Valor, trabajo colaborativo, Inspección y adaptación y mejoramiento continuo. Propuestas y experimentos, mejores prácticas y calidad de los productos (de software) y servicios.
Buscar en Gazafatonario IT
lunes, junio 02, 2014
Libro: Asuntos de la Ingeniería del Software- volumen II
martes, octubre 02, 2012
Casos de Abuso, Parte 11: Cada caso de uso se diseña e implementa de manera independiente
miércoles, abril 11, 2012
Sobre “interpretación” vs. “realización” de casos de uso
Es decir, esperamos que la especificación de un caso de uso, por ejemplo, contenga los elementos básicos de un caso de uso, como el Actor, la secuencia básica y las alternativas (si existen), las pre y pos-condiciones y los requisitos especiales, entre otras. Pero también esperamos que tenga la así llamada “realización del caso de uso”.
Esta no es más que el análisis y diseño del caso de uso, o sea, la manera como se va a implementar ese caso de uso en términos de diseño. Normalmente para esto usamos diagramas de UML, los que sean necesarios, empezando por diagramas de interacción (ya sean de Secuencia o de Comunicación), y también diagramas de Estado o de Actividad, entre otros.
El asunto es que la especificación del caso de uso debe ser lo suficientemente clara (no ambigua) y completa para que cualquier “interpretación” que se haga de la misma arroje los mismos resultados. Y esto debe ser así no solo para el equipo de diseño y de programación, sino para el equipo de pruebas. Es decir, la documentación debe ser tal que el diseñador y el verificador se hagan el mismo modelo o esquema mental del diseño y de las pruebas (casos de prueba) respectivamente.
Algunas técnicas para mejorar la especificación de requisitos (y de casos de uso) incluyen la revisión par, que debe comprender revisión de forma y de contenido. Esta revisión debe validar que cada requisito (y cada caso de uso) cumpla con algunas características bien conocidas:
- Claro
- Atómico
- No ambiguo
- Verificable
- Necesario
- Priorizado
- Correcta
- Independiente de diseño
- Completa
- Consistente
- Rastreable
- Modificable / Extensible
*+*+*+ /*+*+*+ /*+*+*+ /*+*+*+ /*+*+*+ /*+*+*+ /*+*+*+ /*+*+*+ /
PD. Los invito a leer mi artículo sobre Realización de Casos de Uso. Lo encuentran en el enlace adjunto: http://gazafatonarioit.blogspot.com/2007/10/lecturas-fundamentales-10-lectura_3046.html
viernes, noviembre 23, 2007
Lectura Fundamental 11
Lectura Fundamental Anterior: “Realización de Casos de Uso: De los Objetos y sus Interacciones”
Lectura # 11
Orientación a Objetos: Un Enfoque Teórico Moderno (Actualizado)
“Cuando la Generación-Net alcance la mayoría de edad, el mundo será más pequeño e infinitamente más complejo. No tenemos idea de cuáles problemas afrontarán estos jóvenes, cuáles serán sus sueños, ni qué nuevas y audaces soluciones idearán. Pero una cosa es segura: la democracia tal como la conocemos se acabará. Quizás debamos adoptar una actitud seria desde ahora y replantear nuestra noción sobre el gobierno y el significado de la libertad.”
Don Tapscott (Creciendo en un Entorno Digital)
Introducción
En Ingeniería del Software, la clase es la unidad esencial que forma a todo sistema de software. Es además la estructura sistémica y funcional fundamental del software en actividad, capaz de ejecutarse independientemente como entidad mono-funcional (como un servicio), o bien, hacer parte de una formación mayor, como instrumento multi-funcional. La clase presenta dos modelos básicos: abstracto y concreto. Su organización general comprende: identificador de la clase o nombre, atributos o propiedades y operaciones o métodos.
La teoría de la orientación a objetos o simplemente orientada-a-objetos es la base sobre la que se sustenta gran parte de la Ingeniería del Software. Todos los elementos utilitarios que forman los productos de software moderno están formados por clases.
El concepto de clase como unidad orgánica (en el sentido de estructural) y funcional de los sistemas de software surgió hará apenas unos cuarenta años, cuando el término “orientado-a-objetos” fue usado por primera vez.
“En Utah, en algún momento después de Noviembre del 66 cuando, influenciado por Sketchpad, Simula, el diseño para la ARPAnet2, el Burroughs B5000 y mi conocimiento en Biología y Matemáticas, empecé a pensar en una arquitectura para la programación. Y fue probablemente en 1967 cuando alguien me preguntó qué estaba haciendo y le respondí: “Es programación orientada-a-objetos”.”3
Posteriormente, en los años setenta, el Grupo de Investigación en Aprendizaje (Learning Research Group) de XPARC (Xerox Palo Alto Research Center) con el Dr. Alan Kay a la cabeza, desarrolló SmallTalk, el primer lenguaje de programación orientado-a-objetos nativo que fue liberado a principios de los ochenta a toda la comunidad de desarrolladores. Algunas leyes4 o primitivas subyacen el desarrollo del lenguaje:
1. Cualquier cosa es un objeto
2. Los objetos se comunican enviando y recibiendo mensajes (en términos de objetos)
3. Los objetos tienen su propia memoria (en términos de objetos)
4. Cada objeto es una instancia de una clase (la cual puede ser un objeto)
5. La clase contiene el comportamiento compartido para sus instancias (en la forma de objetos en un programa)
6. Para evaluar un programa, el control se pasa al primer objeto y el resto es tratado como su mensaje.
Hoy, todos los lenguajes de programación implementan esas leyes y como programadores deberíamos tenerlas siempre presente a la hora de escribir un programa.
Más tarde se crearon lenguajes como C++, Eiffel y Oberon. En los noventas, Java y hace apenas unos años, ya en este milenio, C# (C Sharp), alrededor de los cuales se han establecido los postulados de la teoría orientada-a-objetos, que afirma, entre otras cosas, que la clase (el objeto) es una unidad morfológica (desde el punto de vista sistémico) de todo sistema de software.
Biología Informática
La célula es la unidad fundamental de los organismos vivos, generalmente de tamaño microscópico, capaz de reproducción independiente y formada por un citoplasma y un núcleo rodeados por una membrana.1
Una célula está compuesta por un Núcleo, el organillo más ilustre en la mayoría de células animales y vegetales. En el núcleo, las moléculas de ADN y proteínas están estructuradas en cromosomas normalmente dispuestos en pares iguales. El ADN del interior de cada cromosoma es una molécula indivisible larga y arrollada que contiene cadenas lineales de genes. Éstos encierran a su vez instrucciones codificadas para la construcción de las moléculas de proteínas y ARN necesarias para producir una copia funcional de la célula, ¡el mismísimo milagro de la vida!
Los otros componentes de la célula son el Citoplasma y el Citosol. El primero comprende todo el volumen de la célula, salvo el núcleo. Engloba numerosas estructuras especializadas y orgánulos. El otro es la solución acuosa concentrada en la que están suspendidos los orgánulos.
Les estoy contando todo esto precisamente porque una analogía muy útil para una célula (biológica) es un objeto (informático). Los objetos tienen instrucciones codificadas dentro de ellos llamadas métodos (o procedimientos o funciones). Los programas en los objetos son análogos a la programación genética en el DNA dentro de las células. El DNA se subdivide en unidades funcionales llamadas genes; estas unidades corresponden a los atributos (o variables) en el objeto. Un objeto también tiene un metabolismo: consume memoria de acceso aleatorio (léase RAM) o hasta de sólo lectura (ROM).
Tanto los programas en las células como los métodos en los objetos pueden ser 1) copiados y 2) ejecutados. Algunas de las proteínas creadas cuando un programa genético se ejecuta corresponden a los resultados o salidas de los procedimientos y funciones del objeto. Pero otras proteínas son más análogas a los componentes de la clase o a las interfaces de la misma con el entorno. Por supuesto, los objetos no crean sus propios métodos o sus interfaces, lo hacen los programadores; la analogía no es perfecta.
De hecho, nada en los objetos es análogo a la reproducción de una célula. Una célula puede crear una copia completa de sí misma; esta célula contiene las instrucciones completas (programas) y la maquinaria celular (hardware) necesarias para reproducirse por sí misma. Un objeto no puede crear una copia de sí mismo… ¡hasta ahora! Le hacen falta los mecanismos necesarios (pero puede ser capaz de reproducir su conjunto de instrucciones respondiendo a un mensaje de su entorno, por ejemplo.) Un objeto que pueda reproducirse por sí mismo sería mejor descrito como un robot-software auto-reproductor. Tal cosa es concebible, pero no existe hoy.
Una criatura multiceldada es como un diagrama de clases. Se requiere de una arquitectura orientada a objetos, paralela, a gran escala para operar criaturas multiceldadas tales como mamíferos con billones o trillones de celdas, todas trabajando en armonía, cada una haciendo su tarea. El sistema nervioso y el sistema hormonal son dos importantes sistemas en red usados por los mamíferos.
Cambiar la forma en que un objeto trabaja requiere de novedosos y más avanzados algoritmos. Algunas veces un programador puede simplemente codificar un conjunto nuevo de órdenes de Inteligencia Artificial: el objeto reconoce el nuevo método o procedimiento, acepta su nuevo código y lo usa. Otras veces, reprogramar un objeto es más traumático. Las nuevas funciones pueden tener “errores”; puede no ser compatible desde el punto de vista de la lógica con el comportamiento existente en el objeto; se pueden llegar a necesitar parches adicionales; se puede introducir un virus de computador; o puede causar que el todo el objeto, y con ello el sistema del que hace parte, colapse sin explicación.
La evolución biológica sucede cuando las células son reprogramadas. De una forma u otra, los nuevos programas genéticos son instalados y activados. ¿Cómo se consigue instalar y activar nuevo software genético? ¿Y de dónde viene? Estas son algunas de las preguntas que la Cósmica Ancestral22 intenta responder.
Mientras encontramos estas y otras respuestas fundamentales, volvamos a nuestro hemisferio.
Conceptos Fundamentales
Una suite de conceptos, unos básicos o fundamentales, otros más avanzados, desde el punto de vista de la semántica, son necesarios para entender la teoría de la orientación a objetos.
Definición 22: Clase. Una descripción de un conjunto de objetos que comparten los mismos atributos, operaciones, métodos, relaciones y semántica. Una clase puede usar un conjunto de interfaces para especificar colecciones de operaciones que ella proporciona a su entorno.5
Una clase puede ser vista como una plantilla o molde, un prototipo funcional, a partir del cual se pueden crear o instanciar un conjunto de elementos con las mismas características y comportamientos llamados Objetos. La clase es la unidad básica, el equivalente de la célula en el ser humano, que forma todo sistema de software. Una clase representa un grupo de datos y la manipulación de estos datos. Como piezas de datos, las clases pueden ser manipuladas. Sin embargo, como procedimientos, las clases también describen la manipulación. La información se manipula enviando un mensaje a la clase que representa la información.
Tiene sentido: puesto que un sistema de software es una herramienta para manipular información, las clases son esos diminutos corpúsculos, invisibles, que forman un sistema de software. Para los propósitos de este artículo, estoy usando una definición muy amplia de información.
Definición 23: Información. Una representación o descripción de algo.6 Hay muchos tipos de información que describen diferentes cosas en formas diversas. Uno de los grandes sucesos en la computación fue el hecho de que la información podía, entre otras cosas, describir la manipulación de la información. Este tipo de información es llamada software.
En el mundo real, los seres humanos no concebimos una estructura (una cosa) sin pensar al mismo tiempo en el comportamiento que presenta o puede presentar esa estructura (esa cosa). Esta fue la premisa que alimentó la investigación del LRG en XPARC. Y debería ser el punto de partida en el desarrollo de cualquier producto de software. Es el orden natural de las cosas: las clases, al menos las primeras que aparecen de la mano de los usuarios, provienen precisamente del mundo real que, en términos del ciclo de vida o del proceso de desarrollo, constituyen lo que se llama el modelo de dominio. Alrededor de estas clases aparecen otras, durante el análisis y el diseño del software, que apoyan la operación “automatizada” de las primeras.
Ejemplos de clases típicas son: Proveedor, Cliente, Factura, Producto, Contrato, Pago (vemos una clase puede representar Personas, Cosas o Artefactos y Operaciones transaccionales). Cada una de estas clases tiene un conjunto de atributos o valores o características y un conjunto de métodos o procedimientos. En el caso de Contrato, por ejemplo, los atributos clave serían Número del Contrato, Fecha de Contrato, Valor del Contrato, Objeto del Contrato, Contratante, Contratista, Modalidad del Contrato, entre otros; algunas operaciones que se pueden hacer con el contrato son: Abrir Contrato, Cancelar Contrato, Suspender Contrato, Cerrar Contrato, Extender Contrato, Pagar Contrato. Son operaciones inherentes al negocio, del dominio dentro del cual una empresa rige su negocio.
Definición 24: Modelo de Dominio. Un modelo de dominio es un modelo del dominio dentro del cual una Empresa conduce su negocio. El Modelo de Dominio para una Empresa debería ser el mismo que para cualquier otra Empresa que conduzca el negocio en el mismo dominio. Cuando bajamos a niveles más detallados, personas distintas tienen diferentes ideas acerca de lo que constituye un Modelo de Dominio.
Un modelo de dominio puede verse como un modelo conceptual de un sistema el cual describe las distintas entidades involucradas en ese sistema y sus relaciones. El modelo de dominio es creado para documentar los conceptos clave y el vocabulario del sistema. El modelo muestra las relaciones entre las entidades principales dentro del sistema y usualmente identifica sus métodos y atributos importantes. Esto significa que el modelo proporciona una vista estructural del sistema el cual es complementado por las vistas dinámicas en el modelo de casos de uso. Un beneficio importante de un modelo de dominio es describir y restringir el alcance del sistema.
El modelo de dominio puede ser usado a bajo nivel en el ciclo de vida del desarrollo del software desde que la semántica del mismo puede ser usada en el código fuente. Las entidades se convierten en clases, mientras que los métodos y atributos pueden llevarse directamente al código fuente; los mismos nombres típicamente aparecen en el código fuente.
El modelo de dominio es uno de los artefactos centrales en las más importantes metodologías o procesos de desarrollo de software existentes. En UML, un diagrama de clases se usa para representar el modelo de dominio.
Todas las clases mencionadas en el apartado anterior son clases típicas que conforman un modelo de dominio. Para entender mejor, citemos algunas clases que no harían parte de ningún modelo de dominio: la Clase de Acceso a Datos, El Manejador de Errores (llamado también Controlador de Errores), la clase Usuario (en un contexto de seguridad), El Controlador de Transacciones, la clase de Auditoria, entre muchas otras que hacen parte del diseño de la solución y están fuera del dominio del problema.
Definición 25: Objeto. Una entidad con un límite bien definido e identidad que encapsula un estado y un comportamiento. El estado se representa por los atributos y las relaciones, mientras que el comportamiento es representado por las operaciones, métodos y las máquinas de estado. Un objeto es una instancia de una clase. 7
Un objeto es una entidad individual que satisface la descripción de una clase o tipo.
Definición 26: Instancia. Es una manifestación concreta de una abstracción a la cual un conjunto de operaciones puede aplicarse y que tiene un estado que almacena los efectos de las operaciones.8 Instancia y Objeto son básicamente sinónimos.
Una clase puede derivar muchas instancias. Dicho de otra manera, en un momento determinado se pueden crear una o más instancias u objetos de una clase. El número de instancias creadas a partir de una clase está limitado únicamente por la cantidad de memoria disponible en el computador donde se esté ejecutando la aplicación que usa la clase.
Cada objeto se diferencia del otro por los valores de sus atributos. Este conjunto de valores forman el Estado del Objeto, único para cada instancia. Y observen que estoy usando los términos Instancia y Objeto indistintamente para referirme a lo mismo.
Definición 27: Operación. Un servicio que puede ser requerido desde un objeto para afectar su comportamiento. Una operación tiene una firma, que puede restringir los parámetros reales que son posibles. En otras palabras, una operación es una abstracción de algo que se puede hacer a un objeto que es compartido por todas las instancias de la clase.9
Una clase puede tener cualquier número de operaciones o ninguna operación. Por ejemplo, en una librería de ventanas como la que se encuentra en el paquete awt de Java, todos los objetos de la clase Rectangle pueden moverse, cambiar de tamaño o ser consultados sobre el valor de sus propiedades.
Muchas veces (pero no siempre), invocar una operación sobre un objeto cambia los datos o estado del objeto. En la Orientación a Objetos, una operación recibe comúnmente el nombre de método y en los lenguajes de programación se pueden clasificar en procedimientos y funciones.
En general las clases incluyen algunas operaciones comunes para Crear (create o new) o Destruir (Destroy o Release o Dispose) una instancia.
Además, las operaciones pueden ser públicas, es decir, visibles desde el exterior de la clase, o privadas, las que están disponibles solamente para los objetos de la clase.
Un término bastante relacionado con Operación es Mensaje.
Definición 28: Mensaje. Una especificación de una comunicación entre objetos que transmite información con la expectativa de iniciar una actividad; el recibo (la recepción) de una instancia de un mensaje es considerada normalmente una instancia de un evento. 10
Los mensajes se establecen vía el conjunto de operaciones públicas de una clase.
Definición 29: Protocolo. El conjunto de mensajes a los que un objeto puede responder. 11
Como programadores, lo primero que debemos preguntarnos es cuál será el protocolo de la clase a programar y cuál es el protocolo de la(s) clase(s) relacionadas. Son estos protocolos los que permiten poner en movimiento un proceso (automático), los que permiten el flujo de información y mantener en ejecución por tiempo indefinido un sistema de software.
Definición 30: Interfaz. Una colección de operaciones que son usadas para especificar un servicio de una clase o de un componente.12
La Interfaz es el mecanismo que usan los lenguajes de programación para implementar un Protocolo.
Definición 31: Atributo. Un atributo definido por una clase representa una propiedad nombrada de la clase o sus objetos. Un atributo tiene un tipo que define el tipo de sus instancias. 13
El conjunto de atributos de una clase constituye su Estructura y los valores de esos atributos en un instante dado representan el Estado del objeto.
Normalmente los atributos o propiedades de una clase están ocultos al mundo exterior, es decir, al resto de clases o de entidades que forman un sistema. Solamente se puede acceder a los valores de tales propiedades a través de métodos de la clase dispuestos para tal fin. Algunos de estos métodos son especializados y únicamente son capaces de asignar o “recordar” (leer) el valor de una propiedad, otros lo hacen mediante operaciones o transacciones más o menos complejas. Hay atributos que sólo pueden ser vistos por las operaciones de la clase, otros pueden ser vistos además por las clases “hijas” en una jerarquía de clases (ver Herencia).
Sin embargo, la mayoría de los lenguajes de programación implementan mecanismos para que desde el exterior de un objeto, o sea, desde otros objetos se pueda acceder directamente a los valores de las propiedades de una clase. Esto se hace para mejorar el desempeño de las aplicaciones en varios sentidos, sin embargo, deberíamos evitar el uso de estos mecanismos tanto como sea posible.
Definición 32: Relación. Es una conexión semántica entre elementos de un modelo. Ejemplos de relaciones incluyen asociaciones y generalizaciones.14
Las relaciones son los elementos encargados de darle vida a un modelo. Por sí solos, los demás componentes de un modelo como las clases no son capaces de hacer mucho (tal como muchos organismos unicelulares que actúan simplemente como parásitos) y es a través de relaciones como la Asociación, la Composición, la Agregación y la Generalización que se pone un modelo en ejecución.
Como regla general, todas las clases del dominio deberían estar relacionadas entre sí, sin embargo, el número de relaciones entre una clase y otras del modelo debería mantenerse al mínimo, lo que permitirá a su vez una baja dependencia entre el subsistema a los que pertenece una clase y los subsistemas a los que pertenecen las clases relacionadas. Esto se llama el Principio o Patrón de Bajo Acoplamiento.
Definición 33: Asociación. Una asociación es una relación estructural que especifica que objetos de una cosa están conectados con objetos de otra. Dada una asociación que conecta dos clases, podemos relacionar objetos de una clase con objetos de la otra clase. Es legal tener ambos extremos de una asociación sobre la misma clase, de manera circular. Esto significa que, dado un objeto de la clase, podemos enlazar a otros objetos de la misma clase. Una asociación que conecta exactamente dos clases se llama una asociación binaria. Aunque no es común, podemos tener asociaciones que conectan más de dos clases; éstas son llamadas asociaciones n-arias. Usamos asociaciones cuando queremos mostrar relaciones estructurales.15
En principio, durante las etapas de Análisis, todas las clases del dominio deberían estar “asociadas” entre sí. Más adelante, hacia el final del análisis y en el diseño, algunas asociaciones se pueden convertir en otro tipo de relaciones y las que permanecen como asociaciones se deben cualificar.
La cualificación de una relación como la asociación se logra mediante la cardinalización de ambos extremos de la relación, lo mismo que con el nombramiento, en ambos sentidos, de la misma. Por ejemplo, en un sistema típico tanto la entidad Cliente (de una Compañía) como la entidad Proveedor (de la misma Compañía) tienen alguna forma de relación (de asociación) con la entidad Producto. Pero a todas luces se evidencia la diferencia existente en la relación entre Proveedor y Producto que entre Cliente y Producto.
El Proveedor “vende” o “provee” de productos a la compañía, mientras que el Cliente “compra” o es “surtido” de productos por la compañía. En este contexto, “proveer”, “vender”, “comprar” y “surtir” son nombres representativos de asociaciones.
A su vez, es probable que un Proveedor suministre uno o más productos a la compañía (y hasta puede suceder, por políticas de la compañía –regla del negocio-, que quizás haya un máximo número de productos que un proveedor pueda suministrar, por ejemplo, 5). También puede ocurrir que para ser considerado como tal, un Cliente de la compañía deba comprar o adquirir mínimo 2 productos y máximo 12. Estos rangos (uno o más productos, 1 a 5, 2 a 12) hacen parte de la cardinalidad de las asociaciones.
Definición 34: Generalización. Es una relación entre un tipo general de una cosa (llamada la superclase o padre) y un tipo más específico de cosa (llamada la subclase o hija). Algunas veces, la generalización es llamada una relación “es-un-tipo-de”: una cosa (como la clase Baywindow) es-un-tipo-de una cosa más general (por ejemplo, la clase Ventana). Un objeto de la clase hija puede ser usado para una variable o parámetro tipado por el padre, pero no a la inversa. En otras palabras, la generalización significa que la hija es sustituible para una declaración del padre. Una hija hereda las propiedades de sus padres, especialmente sus atributos y operaciones. Muchas veces pero no siempre la hija tiene atributos y operaciones en adición a los encontrados en sus padres. Una implementación de una operación en una hija anula una implementación de la misma operación del padre; esto se conoce como polimorfismo. Para ser la misma, dos operaciones deben tener la misma firma (mismo nombre y parámetros). Use generalizaciones cuando quiera mostrar las relaciones padre/hija.16
La generalización es una relación taxonómica entre un elemento más general y un elemento más específico. El elemento más específico es completamente con el elemento más general y contiene información adicional. Una instancia del elemento más específico puede usarse donde el elemento más general es permitido.
Definición 35: Herencia. Es el mecanismo que hace posible la generalización; un mecanismo para crear descripciones completas de clases a partir de segmentos de clases individuales.17
En Orientación-a-Objetos, dada una clase, con unas características y un comportamiento bien definidos, se puede crear una jerarquía de clases, en donde cada clase de la jerarquía “hereda” los atributos y las operaciones de todos sus ancestros. El elemento hereditario además puede tener características y comportamiento propios o adicionales a los de los demás miembros de la estructura taxonómica a la que pertenece.
La herencia aparece cuando tipificamos o clasificamos elementos de un modelo, cuando decimos que este elemento “es-una-clase-de” o “es-un-tipo-de”. Por ejemplo un (Animal) Mamífero es una clase de Animal, un Automóvil es un tipo de Transporte Terrestre, un Vendedor es una clase de Persona.
Definición 36: Agregación. Una asociación plana entre dos clases representa una relación estructural entre pares, lo que significa que ambas clases están conceptualmente al mismo nivel, ninguna es más importante que la otra. Algunas veces queremos modelar una relación “todo/parte” en la que una clase representa una cosa más grande (el “todo”), que consiste de cosas más pequeñas (las “partes”). Este tipo de relación se llama agregación, que representa una relación “tiene-un” que significa que un objeto del todo tiene objetos de la parte. La agregación es realmente una clase especial de asociación.18 Una de las grandes diferencias de la Agregación con la Asociación es que las instancias no pueden tener relaciones de agregación cíclicas, es decir, una parte no puede contener al todo.
La agregación se convierte en un concepto simple con alguna semántica moderadamente profunda. La agregación simple es enteramente conceptual y no hace nada más que distinguir un “todo” de una “parte”. La agregación simple no cambia el significado de la navegación a través de la asociación entre el todo y sus partes, ni enlace los ciclos de vida del todo y sus partes.
La multiplicidad de la parte agregada no puede ser mayor a 1, esto quiere decir que no es compartida.
Definición 37: Composición. Hay una variación de la agregación simple, la composición, que adiciona cierta semántica importante. La composición es una forma de agregación con propiedad fuerte y ciclos de vida coincidentes como parte del todo. Partes con multiplicidad no fija pueden ser creadas después del compuesto mismo, pero una vez creadas viven o mueren con ella. Tales partes también pueden ser explícitamente removidas antes de la muerte del compuesto.19 A la Composición también se le conoce como Agregación Compuesta.
Esto significa que, en una agregación compuesta, un objeto puede ser una parte de sólo un compuesto a la vez. Por ejemplo, en un sistema de Ventanas, un Marco pertenece a exactamente una Ventana. Esto contrasta con una agregación simple en la que una parte puede ser compartida por varias partes. Por ejemplo, en el modelo de una casa, una Pared puede ser una parte de uno o más objetos Cuarto.
Además, en una agregación compuesta el todo es responsable por la disposición de sus partes, lo que significa que el compuesto debe manejar la creación y destrucción de sus partes. Por ejemplo, cuando creamos un Marco en un sistema de ventanas, debemos adicionarlo a una Ventana. Similarmente, cuando destruimos una Ventana, el objeto Ventana debe a su vez destruir sus partes Marco.
El control que mantiene el “todo” con la “parte” puede ser directo o transitivo, o sea, el “todo” puede tener la responsabilidad directa de crear o destruir la “parte” o puede aceptar una parte previamente creada y más tarde pasarla a algún otro “todo” que asuma la responsabilidad por esa “parte”.
Un objeto puede ser parte de solamente un compuesto a la vez. Si el compuesto es destruido, este debe destruir todas sus partes o pasar la responsabilidad de ellos a algún otro objeto. Un objeto compuesto puede ser diseñado con el conocimiento de que ningún otro objeto podrá destruir sus partes.
Un ejemplo típico de una composición es el del Automóvil: las puertas, la carrocería, las llantas y el motor, por sí solos pueden no tener ninguna utilidad (funcionalidad), pero compuestos, bien podríamos tener un (objeto) buen automóvil que nos presta una mayor utilidad (funcionalidad), seguramente mayor que la suma de sus partes.
Definición 38: Polimorfismo. Generalmente, la habilidad aparece en muchas formas. En programación orientada-a-objetos, el polimorfismo se refiere a la habilidad de un lenguaje de programación de procesar objetos de manera diferente dependiendo de su tipo de dato o clase. Más específicamente, es la habilidad de redefinir métodos para clases derivadas.20 Por ejemplo, dada una clase base Figura_Geometrica, el polimorfismo habilita al programador para definir métodos CalcularArea diferentes para cualquier número de clases derivadas, tales como círculos, rectángulos y triángulos. Sin importar de qué forma es un objeto, aplicarle el método CalcularArea retornará los resultados correctos. El polimorfismo es considerado un requisito de cualquier lenguaje de programación orientado-a-objetos (OOPL).
En otras palabras, dada una jerarquía de objetos, cada objeto implementa su(s) comportamiento(s) de acuerdo a sus características. La operación para calcular el área de un triángulo (Base X Altura / 2) es diferente de la operación para calcular el área de un círculo (π X Radio2) porque evidentemente tienen atributos distintos como bien sabemos.
Definición 39: Abstracción. Es un mecanismo y práctica para reducir y factorizar los detalles de tal manera que podamos enfocarnos en unos pocos conceptos al tiempo.21
El concepto se da por analogía con la abstracción matemática. La técnica matemática de abstracción comienza con definiciones matemáticas; esto tiene el efecto afortunado de afinar algunos de los aspectos filosóficos molestos de abstracción. Por ejemplo, tanto en computación como en matemáticas, los números son conceptos en los lenguajes de programación, tal como se encuentran en las matemáticas. Los detalles de implementación dependen del hardware y del software, pero esto no es una restricción porque el concepto computacional de número todavía está basado en el concepto matemático.
La abstracción puede aplicarse tanto al control del proceso como a los datos manipulados por el proceso. La abstracción de control es la abstracción de acciones mientras que la abstracción de datos aplica a las estructuras. Por ejemplo, la abstracción de control en programación orientada a objetos tiene que ver con el uso de métodos, interfaces y clases genéricas. La abstracción de datos permite el manejo de datos de maneras significativas. Por ejemplo, es la motivación básica detrás de los tipos de datos. Finalmente, la Programación orientada-a-objetos puede verse como un intento de abstraer tanto el dato como el código.
De Dónde Surgen los Objetos
Parece justo, al menos para mí, terminar esta disertación sobre orientación a objetos con un aspecto del que tengo algún conocimiento: la Gramática, en particular, y el lenguaje, en general. Por supuesto no hablo de C#, Java o C++, algunos de los lenguajes de programación más ampliamente usados hoy, estoy hablando del idioma Español.
Luego de tener un manifiesto con los requisitos del sistema (y por sistema también quiero decir un módulo, un subsistema, un proceso, un modelo), expuestos en distintos artefactos como un documento de visión, un glosario, una descripción detallada de esos requisitos, un conjunto finito de casos de uso (hoy se llaman casos de uso, Jacobson 1994, ayer se llamaban escenarios, Rumbaugh 1991), entonces procedemos a realizar un análisis sintáctico, pero no de esos que hacen los compiladores, no. Estoy hablando de una exploración minuciosa de todas y cada una de las frases del manifiesto y hacer una tabla con los sustantivos, los verbos, los adjetivos, los adverbios. Si de pronto hemos olvidado lo que es un Predicado o lo que es un Adverbio de Lugar, entonces hay que volver a sacar el libro Español y Literatura de nuestra queridísima maestra Lucila González de Chávez y repasar algunos detalles sobre el tema.
Los sustantivos son clases o atributos potenciales (en este período mesozoico del proceso todavía no somos capaces de acertar en el primer intento sobre que elemento de nuestras fuentes documentarias es que elemento de nuestro modelo objetual). Entre tanto, los verbos son métodos potenciales (incluso, podrán llegar a ser procedimientos almacenados o triggers).
¿Y los adjetivos y los adverbios dónde se quedan? Bueno, dice mi Gazafatonario y doña Lucila González que un adjetivo califica al sustantivo (hay muchas clases de adjetivos), le da un valor, esa es la clave: si finalmente nuestro sustantivo es una propiedad, el adjetivo posiblemente sea su valor predeterminado, mientras que si es una clase, el calificativo será una instancia. Por su parte, el adverbio califica al verbo (¿recuerdan? Adverbios de modo, de lugar, de tiempo, demostrativos, relativos, interrogativos, de cantidad e intensidad), una teoría lingüística interesante y profunda que si la conocemos bien nos ayudará a encontrar cuál es el desempeño que se quiere para el método (adverbio de modo), dónde se ejecuta el método (adverbio de lugar) –quizás nos diga de qué clase es, en qué capa de la arquitectura va, si puede ser un trigger o no y cuándo se ejecuta (adverbio de tiempo), algunos criterios funcionales (adverbios demostrativos, relativos, interrogativos), cuál es la frecuencia de ejecución (adverbios de cantidad e intensidad), y hasta pueden llegar a ser argumentos del método en cuestión.
El tema tiene tanto de ancho como de profundidad y no quiero extender más esta lectura, así que los invito a que revisen la extensa literatura que existe sobre ello.
El Siguiente Paso en la Evolución
Fue por allá a mediados de los años 80 cuando escuché y leí por primera vez sobre la orientación a objetos. El término realmente me pareció interesante pero extraño. En contraste, algunos otros compañeros que todavía no habían tenido su primera vez con computadores encontraron la idea de los sistemas orientados a objeto como algo natural. No es que los programadores novatos puedan crear sistemas complejos en un ambiente orientado a objetos más fácilmente de lo que pueden los programadores experimentados. Ciertamente, crear sistemas complejos envuelve muchas técnicas más familiares al programador experto que al principiante, sin tener en cuenta si se usa o no un entorno orientado a objetos. Pero la idea básica acerca de cómo crear un sistema de software en un estilo orientado a objetos llega de una forma más natural a quienes no tienen una preconceptualización acerca de la naturaleza de sistemas de software. Entender los conceptos que he expuesto fue la clave que condujo mi carrera profesional durante mucho tiempo y que me permitió escribir algunos cientos de miles de líneas de código en diversos lenguajes de programación.
Muchos años después, con el advenimiento de la Internet, me di a la tarea de buscar y conocer en qué andaba el célebre equipo de XPARC que creó la técnica tan acertadamente. Los encontré en www.parc.com y el mundo de la programación no volvió a ser igual para mí.
Los amigos de PARC habían encontrado muchos problemas de programación para los que ni las técnicas de programación procedimental ni orientadas a objeto parecían suficientes para capturar claramente algunas de las decisiones importantes que un programa debía implementar. Ellos observaron que esos problemas forzaban la implementación de muchas decisiones de diseño en el código de una manera dispersa y heterogénea, dando como resultado un código fuente “enmarañado” que es difícil de desarrollar y mantener. Así es que presentaron a la comunidad un análisis del porqué ciertas decisiones de diseño eran difíciles de capturar apropiadamente en el código actual y llamaron a las propiedades a las que esas decisiones apuntaban aspectos. También mostraron que la razón de su captura compleja era que estas decisiones eran transversales a la funcionalidad básica de todo sistema. Con esto en mente, presentaron las bases para una nueva técnica de programación que llamaron programación orientada a aspectos o simplemente aspectos. Esta técnica hace posible escribir programas con precisión que involucren tales aspectos, incluyendo aislamiento apropiado (más allá de la encapsulación de objetos), composición y reusabilidad de código “aspectual”.
En breve, los Aspectos son propiedades para las cuales la implementación no puede ser encapsulada en un procedimiento generalizado. Los Aspectos y los componentes transversales se cruzan entre sí en la implementación de un sistema. Esta técnica soporta una abstracción completa y la composición tanto de componentes como de aspectos. La diferencia clave entre AOP y la OOP (y por extensión con PPO) es que la AOP proporciona lenguajes de componentes y aspectos con diferentes mecanismos de abstracción y composición.23
Los Aspectos son a los Objetos lo que estos fueron a los Procedimientos. Hoy ya existen lenguajes orientados a aspectos como AspectJ (la primera implementación de un lenguaje AOP basado en Java), AspectC++, Aspicere2 y otros basados en C/C++; también existen LOOM.NET, AspectDNG, Compose, Aspect.NET, DotAspect y otros basados en C#/VB.NET y muchas otras docenas de estos lenguajes emergentes, incluyendo WEAVR de Motorola para UML 2.0, una herramienta de desarrollo de software Orientado a Aspectos de naturaleza industrial que soporta weaving de los modelos comportacionales de UML 2.0 como los diagramas de interacción y de actividad. Y es tiempo de un último aserto.
Definición 40: Weaving es el proceso de aplicar Aspectos a los Objetos Destinatarios para crear los nuevos Objetos Resultantes en los especificados Puntos de Cruce. Este proceso puede ocurrir a lo largo del ciclo de vida del Objeto Destinatario:
· Aspectos en Tiempo de Compilación, que necesita un compilador especial.
· Aspectos en Tiempo de Carga, los Aspectos se implementan cuando el Objeto Destinatario es cargado en la máquina virtual.
· Aspectos en Tiempo de Ejecución.
Está ocurriendo tal cual ha ocurrido durante millones de años en la naturaleza, las insuficiencias existentes, los entornos recién descubiertos, recién creados, sólo dan paso a los más fuertes y sólo los más arriesgados sobreviven, así es la biología celular. Así mismo pasa en la TI, las nuevas necesidades exigen nuevas soluciones y estas a su vez requieren de nuevas tecnologías y nuevas técnicas.
En el futuro lejano, luego de la fusión de tres revoluciones científicas que todavía no ocurren, la teoría cuántica nos proveerá de transistores cuánticos microscópicos más pequeños que una neurona, la revolución informática nos facilitaría redes neuronales tan poderosas como las que hoy residen en el cerebro humano, y la revolución biomolecular nos permitiría la capacidad de reemplazar las redes neuronales de nuestro cerebro por tejidos sintetizados, garantizándonos así cierta condición de renovación, seríamos inmortales.
Pero no nos apresuremos, un paso a la vez, “así se ha hecho durante millones de años” 24, así que todo esto será motivo de otra de mis lecturas.
Conclusión
He abordado sucintamente los conceptos que subyacen la técnica de la programación orientada a objetos. Es lo que existió antes del lenguaje de programación, antes del Java y el C#, aún antes del BASIC y el C. Entender estos conceptos nos da una visión que permite reducir la complejidad de grandes sistemas sin poner complicaciones adicionales en la construcción de sistemas pequeños. Ciertamente, como lo pensaron los investigadores en XPARC durante 20 años de estudios, la técnica se acerca a la forma cómo pensamos los seres humanos; sin embargo, todavía el hardware disponible hoy, otros 30 años después, es incapaz de aceptar tales principios. Quizás en el futuro próximo, ayudados por lo que he dado en llamar Biología Informática, podamos tener máquinas casi tan hábiles como nosotros, máquinas que entretejan (como los Aspectos), millones de chips neuronales que se crucen ad-infinitum y sean capaces de pensar y adaptarse a nuevos entornos.
Mientras tanto, la programación orientada a objetos, y con ésta, el análisis y diseño orientados a objeto, la programación orientada a aspectos, la herencia y el polimorfismo, las asociaciones binarias y las abstracciones lógicas, serán las técnicas que reinen en el mundo de las tecnologías informáticas.
Cierre y fin de la emisión.
Referencias
1. Diccionario de la Real Academia de la Lengua Española Edición En Línea. http://buscon.rae.es/draeI/SrvltConsulta?TIPO_BUS=3&LEMA=célula
2. ARPANet fue el nombre original de Internet. ARPA son las siglas en inglés de Advanced Research Projects Agency, que inicialmente conectó cuatro grandes computadores en universidades en el suroeste de los Estados Unidos (UCLA, Stanford Research Institute, UCSB y la Universidad de Utah) por allá en 1.969.
3. Dr. Alan Kay. On The Meaning of “Object-Oriented Programming” (http://www.purl.org/stefan_ram/pub/doc_kay_oop_en)
4. Dr. Alan Kay. The Early History of Smalltalk. http://gagne.homedns.org/~tgagne/contrib/EarlyHistoryST.html
5. IBM. The Rational Unified Process Glossary.
6. Luis Antonio Salazar Caraballo. Sistemas de Software Orientado a Objetos. 2000.
7. IBM. The Rational Unified Process Glossary.
8. IBM. The Rational Unified Process. UML.
9. IBM. The Rational Unified Process Glossary.
10. IBM. The Rational Unified Process. UML.
11. Luis Antonio Salazar Caraballo. Sistemas de Software Orientado a Objetos. 2000.
12. IBM. The Rational Unified Process. UML.
13. IBM. The Rational Unified Process. UML.
14. IBM. The Rational Unified Process. UML.
15. IBM. The Rational Unified Process. UML.
16. IBM. The Rational Unified Process. UML.
17. IBM. The Rational Unified Process. UML.
18. IBM. The Rational Unified Process. UML.
19. IBM. The Rational Unified Process. UML.
20. IBM. The Rational Unified Process. UML.
21. Wikipedia contributors, 'Abstraction (computer science)', Wikipedia, The Free Encyclopedia, 7 November 2007, 04:20 UTC, <http://en.wikipedia.org/w/index.php?title=Abstraction_%28computer_science%29&oldid=169781888> [accessed 21 November 2007].
22. Wikipedia contributors, 'Cosmic ancestry', Wikipedia, The Free Encyclopedia, 26 April 2007, 23:28 UTC, <http://en.wikipedia.org/w/index.php?title=Cosmic_ancestry&oldid=126264933> [accessed 21 November 2007]
23. Kiczales, Lamping, Mendhekar, Maeda, Videira Lopes, Loingtier & Irwin. Aspect-Oriented Programming. 1997.
24. Así le dice Ted a Ellie en Contacto, de Carl Sagan.
Ted: Este ha sido un primer paso. Con el tiempo, daréis otro.
Ellie: Pero otros necesitan ver lo que he visto yo.
Ted: Así se ha hecho durante millones de años. Poco a poco, Ellie. Poco a poco.
(Le besa la frente. Ambos miran al cielo. Cientos de rayos, como cometas, se
aproximan a la nebulosa rojiza. Al chocar con ella, hay como una explosión
blanca. Volvemos a la realidad, con la cápsula cayendo bruscamente al agua…)