Académique Documents
Professionnel Documents
Culture Documents
Los actores son personas, los casos de uso son elipses y las comunicaciones son lneas. Los actores pueden ser cualquier entidad externa, incluso otros sistemas, y una misma persona puede actuar en varios roles a la vez.
Anlisis
El anlisis consiste en convertir los requerimientos en abstracciones ms cercanas al programa a construir. Esto lo hace difcil de distinguir del diseo, pero en realidad la principal diferencia consiste en que el anlisis es independiente de cualquier cuestin tecnolgica o implementacin, mientras que el diseo no. As mientras en el anlisis hay que encontrar clases y objetos, en el diseo se piensa en las abstracciones y mecanismos que sirvan para soportar el comportamiento. Hay dos aspectos que deben determinarse en el anlisis: 1. La estructura de los objetos del espacio del problema: cmo se relacionan los objetos, cmo se organizan en tipos, jerarqua de los tipos, anlisis de composicin de objetos. 2. El comportamiento de los objetos del espacio del problema: en qu estados puede estar cada objeto, con qu transiciones y eventos cambia de estado, las operaciones a las que responde y su semntica.
La separacin de tareas en paralelo se hace mediante una barra gruesa, y lo mismo ocurre con su unin posterior. Un rombo permite denotar ramificaciones basadas en alguna condicin. Se pueden usar para modelar: Flujos de procesos. Especificacin de comportamiento de alto nivel. Especificacin de algoritmos. Actividades concurrentes. Secuencialidades innecesarias en procesos de negocio. Distintos agentes u objetos en un flujo.
Las interacciones y comportamientos que abarcan varios casos de uso, posiblemente concurrentes. Casos de prueba.
Un diagrama de colaboracin es, como el diagrama de secuencias, otro diagrama de interaccin. A continuacin se muestra un diagrama de colaboracin, que corresponde al diagrama de secuencia de una interaccin con un cajero automtico:
Los diagramas de interaccin (secuencia o colaboracin) se usan para modelar: Cmo un escenario puede ser realizado a travs de un conjunto de mensajes entre objetos. Las operaciones (mtodos) de las clases. Distintos objetos trabajando en conjunto. Mensajes asncronos. El diagrama de colaboracin enfatiza relaciones estructurales entre objetos y es una herramienta til para encontrar objetos. Muestra tanto la estructura esttica (enlaces) como la dinmica (envo de mensajes). Sirve para ver las conexiones entre objetos, como vnculos conceptuales o de dependencia. Objetos e interacciones, pero privilegiando las relaciones entre los distintos objetos. El diagrama de secuencia enfatiza el ordenamiento temporal y el ciclo de vida de los objetos. Representacin temporal de los objetos y sus interacciones.
Tarjetas CRC
Las tarjetas CRC (clases, responsabilidades y colaboradores) son una herramienta muy til para la bsqueda de las clases de anlisis. Responsabilidad: es todo lo que una clase conoce o hace. De una sola responsabilidad podrn surgir varios mtodos. Para encontrar responsabilidades, as como para las clases se usan los sustantivos de los documentos de requerimientos, podemos utilizar los verbos.
Colaborador: es una clase que provee informacin a la clase en cuestin o realiza alguna accin en respuesta a un mensaje de la misma. Las tarjetas CRC permiten determinar una especie de contrato u obligacin de la clase. La idea consiste en describir cada clase en tarjetas de no ms de 10x15 cm67, en la cual se escribe el nombre de la clase, sus responsabilidades y colaboradores. Ejemplo:
Si alguna de estas clases es un contenedor, las clases de los objetos contenidos deben figurar entre las colaboraciones y debern aparecer en otras tarjetas. Si en algn momento no alcanza la tarjeta para describir las colaboraciones o las responsabilidades de una clase, habr que preguntarse si la misma no debera ser separada en dos clases ms simples.
Diseo de arquitecturas
El diseo como puente entre el anlisis y la implementacin Diseo
Es el cmo del desarrollo. Es la fase ms ingenieril del desarrollo del software, pese a llamarse arquitectura. Se aplica para concebir una solucin a un problema, creando una estructura interna clara y lo ms simple posible. Mnimamente, como resultado del diseo deberamos poder exhibir: Las clases de diseo y las de implementacin, con su estructura, operaciones y semntica. Las distintas arquitecturas del sistema. Otras decisiones de diseo. Las clases de diseo son aquellas que, si bien describen conceptos de alto nivel, como las clases de anlisis, no pertenecen al dominio del problema sino al de la solucin. Las clases de implementacin son las que surgen por necesidades algortmicas, como un tipo de arreglo, lista o fecha definidos por el programador. Entre las decisiones de diseo que no corresponden a arquitecturas ni al diseo de clases estn:
Definiciones sobre implementacin: explicita los lenguajes, herramientas y nomenclatura que se van a utilizar en la programacin, adems de la plataforma de software de base. Definiciones de interfaz de usuario: precisa el tipo de interfaz de usuario, sus elementos principales en cada caso, relaciones entre ellos y normas de usabilidad.
Arquitecturas
Las arquitecturas son formas de descomponer, conectar y relacionar partes de un sistema. Pueden ser de diversos tipos: Arquitectura de componentes, en general llamada simplemente arquitectura, es una visin de alto nivel del sistema que consiste en una descripcin de sus principales componentes de software y sus interacciones (se habla de arquitectura MVC, arquitectura de 3 capas, etc.). Suele estar basada en patrones de diseo. Arquitectura de hardware: define el despliegue de los distintos componentes en los nodos de hardware. En ocasiones incluye la arquitectura de seguridad (firewalls, proxies, etc.). Arquitectura de conectividad: se refiere a los protocolos y dispositivos a usar. Arquitectura de datos: estructura de las bases de datos y la persistencia.
En cualquiera de los dos modelos vemos la idea del dilogo o interfaz de usuarios, tambin llamado interaccin humano-computadora (o HCI, por su sigla en ingls), que es el intercambio observable de informacin, datos y acciones, mediante los cuales el ser humano dice a la computadora lo que quiere y la computadora comunica resultados.
10
HCI es adems una disciplina que se encarga del diseo, evaluacin e implementacin de sistemas informticos interactivos para el uso humano. Esta disciplina ha adquirido una especial importancia por una serie de factores, entre los cuales destacan: La interfaz de usuario se convirti en un factor decisivo en la eleccin del software, de modo tal que hay un alto ndice de software desechado por proveer una interfaz de usuario de baja calidad. Inclusin de la computacin en todos los ambientes e integracin de la informtica a otras reas. Menor costo en hardware, que ha provocado un mayor avance tecnolgico relativo de la interaccin humano-mquina. El auge de Internet y la World Wide Web, con su correlato de aumento de la heterogeneidad en el espectro de usuarios. Si tomamos la definicin de un programa como dilogo ms cmputo, podemos ver que estas dos partes difieren bastante, como muestra el cuadro que sigue:
Interfaz de usuario o componente de dilogo Dependiente de la tecnologa Muy cambiante y sujeto a modas pasajeras Modelo o componente de cmputo Independiente de la tecnologa Ms estable
Estas diferencias hacen que se pueda separar la interfaz del usuario del sistema de aplicacin desde el inicio del desarrollo. Lo que se buscaba era: Presentacin y control dinmicos de la informacin. Mltiples formatos de salida (por ejemplo, a un monitor, una base de datos o un archivo XML). Mltiples forma de mostrar la misma informacin (diagramas de torta y de barras, por ejemplo). Mltiples tipos de estmulos del usuario (por ejemplo, teclado y mouse). De esta forma se buscaba lograr ciertos objetivos, entre los que destacan: Modificabilidad. Simplicidad. Escalabilidad. Independencia de la tecnologa. Posibilitar el cambio de modelo sin modificar la interfaz de usuario. Posibilitar la evolucin de la interfaz de usuario sin cambiar el modelo.
11
Desarrollar mltiples interfaces de usuario para un mismo modelo. Poder separar fsicamente la lgica de una aplicacin distribuida, que reside en una computadora remota, de los resultados mostrados en mquinas clientes. Con base en estos requisitos, hubo varias propuestas destinadas a separar los componentes de dilogo y cmputo, destacndose la arquitectura MVC.
MVC
MVC es un patrn de arquitectura orientado a objetos que consiste en separar la aplicacin en tres partes relativamente independientes: modelo, vista y controlador. Ha demostrado ser muy adecuado en aplicaciones con alta interaccin con el usuario. Se basa en el patrn de diseo Observador. Es bueno en aplicaciones de mucha IU. Se suele combinar con otros. Facilita cambios. Muchas vistas por cada modelo. El modelo es el conjunto de clases y objetos correspondientes a la lgica de la aplicacin (estados y funcionalidad). La idea es que este modelo tenga un bajo acoplamiento con vistas y controladores. Toda la interaccin se debe hacer mediante mtodos de consulta, que informen el estado del modelo, comandos que permitan modificar dicho estado y mecanismos de notificacin para informar a los observadores o vistas. La vista es la parte del sistema que administra la visualizacin y presentacin de la informacin. Su principal tarea es observar al modelo para actualizar las variaciones, de modo que la vista represente el estado del modelo, as como los cambios de estado que experimenta el mismo. Es un conjunto de clases y objetos altamente dependientes del dispositivo y la tecnologa de visualizacin, as como tambin del modelo, al que debe conocer bien. Si en el modelo se define una interfaz clara y estable, es fcil implementar mltiples vistas para un mismo modelo. El controlador es el responsable de definir el comportamiento de la aplicacin. Su principal tarea consiste en recibir los eventos del usuario y decidir qu es lo que se debe hacer, mapendolos en comandos (mensajes) hacia el modelo, que eventualmente lo modifican. Como la vista, igualmente el controlador es altamente dependiente de los dispositivos y mecanismos de interaccin del usuario, y tambin debe conocer bien al modelo. En un sistema con interfaz de usuario grfica, una implementacin simple de MVC consiste en un ciclo con la siguiente secuencia:
12
El controlador captura los eventos del usuario para determinar qu objetos estn siendo manipulados. Una vez determinado lo que est ocurriendo, enva mensajes al modelo para generar cambios de estado. El modelo implementa las transformaciones y notifica a la vista. Finalmente, la vista se actualiza para reflejar las novedades. Mecanismos de notificacin por los cuales el modelo puede notificar sus cambios a las vistas: Consulta de estado y respuesta: En este mecanismo, la vista consulta al modelo sobre su estado y se actualiza en consecuencia. El modelo desconoce qu pasa, limitndose a responder a los mensajes recibidos (comandos y consultas). Es la variante ms en consonancia con la POO. Sin embargo, exige a la vista un mayor conocimiento del modelo que en las variantes que siguen. Mediante eventos. Esta es una variante totalmente desacoplada, en la que las vistas escuchan y responden a los eventos de notificacin de sus respectivos modelos, en la medida en que les interesa. El bajo acoplamiento se garantiza haciendo que las propias vistas sean quienes se suscriben en la lista del modelo, permitiendo un manejo totalmente dinmico. Con observadores o vistas asociadas, conocidos por el modelo. Este les enva activamente un mensaje de notificacin, sin informacin, para que luego las vistas se preocupen de actualizarse pidiendo datos al modelo. Este es un mtodo fcil de implementar, y bastante flexible si utiliza eventos tambin.
Los tres mecanismos admiten trabajar con mltiples vistas. La vista y el controlador estn muy interrelacionados, pues ambos dependen de la interaccin con el usuario. Sin embargo, no es as en sistemas web distribuidos, donde la funcionalidad del controlador en parte la maneja el generador de pginas en el servidor (para ello existe un patrn de diseo del controlador denominado controlador de pgina).
13
Ver un sitio web en diversas interfaces de usuario. Manejar una coleccin con varios medios de acceso. Etc.
Las ventajas de este modelo son parecidas a las de MVC, pero ms generales:
14
Posibilitar el cambio de modelo sin modificar la interfaz de usuario o el acceso a los datos. Posibilitar la evolucin de la interfaz de usuario sin cambiar el modelo o la base de datos. Desarrollar mltiples interfaces de usuario o mdulos de acceso a datos para un mismo modelo. Posibilidad de utilizar diferentes herramientas y plataformas en cada capa. Posibilidad de utilizar diferentes paradigmas en capas distintas (por ejemplo, usar orientacin a objetos para el modelo con una base de datos relacional, como veremos en el captulo de persistencia). Cada capa puede ser desarrollada por un equipo distinto, con cronogramas relativamente independientes.
15
La representacin de componentes software se hace con rectngulos con bisagras, que a menudo implementan una interfaz, representada con un crculo pequeo. Las dependencias se representan con flechas discontinuas (dependencia significa que un componente usa servicios de otro).
Diagramas de despliegue
Cmo se despliega un sistema en el hardware. Aplicaciones stand-alone: el sistema est desplegado enteramente en la mquina del usuario. Aplicaciones distribuidas: el usuario accede a un sistema corriendo parcialmente en una mquina remota. Las mquinas remotas pueden ser varias. Ventajas: Especializacin de equipos; seguridad, en algunos casos; si es una web: ms sencillos despliegue y actualizacin. Los diagramas de emplazamiento o despliegue se usan para modelar el despliegue de los distintos componentes de software sobre el hardware y sus vinculaciones.
16
De todas maneras, slo son necesarios en sistemas en los que el hardware sea importante. Los nodos de procesamiento y los componentes que residen en ellos.
Diseo de clases
Buenas prcticas de diseo Encontrando clases de diseo e implementacin
17
Bases del diseo de clases: Una buena arquitectura. Buenas prcticas de diseo y programacin. Patrones de diseo. Un diseo termina cuando no se pueden extraer ms cosas del mismo Eckel. Cada clase con un propsito simple y claro: una clase por abstraccin y una abstraccin por clase. Separar las dependencias de una plataforma en una clase aparte. Patologas en diseo de clases: Clases con nombres verbales: No se supone que una clase hace algo, sino que provee un conjunto de servicios. Clases sin mtodos. Clases que no introducen nuevos mtodos ni los redefinen. Slo heredan. Clases que se refieren a varias abstracciones: se deberan dividir en varias. A veces hay atributos y comportamientos propios de las asociaciones, y en esos casos conviene crear clases para las mismas, llamadas clases de asociacin:
Cohesin y acoplamiento
En la programacin modular existen dos caractersticas que hacen a la calidad de los mdulos: la cohesin, que debe ser lo ms alta posible, y el acoplamiento, que debe ser todo lo bajo que se pueda. Esto facilitar el mantenimiento futuro. La cohesin se refiere a la necesidad de que un mdulo haga una sola cosa simple. Los mdulos de un sistema exhiben alta cohesin.
18
El acoplamiento se refiere a la interdependencia entre mdulos: un bajo acoplamiento garantiza que los mdulos del sistema son relativamente independientes. Asegurar bajo acoplamiento y alta cohesin en mtodos, clases y paquetes.
19
Diseo de implementacin
Llamamos diseo de implementacin a la eleccin de los atributos e implementaciones de mtodos. Conceptualmente, los atributos deberan mostrar slo estado y los mtodos slo comportamiento con pocas bifurcaciones. A veces nos encontramos con mtodos con grandes case/switch en los que se hace una cosa u otra en base al valor de un atributo, como en el ya visto: if (unaFigura.getClass() == Elipse.class) (Elipse)unaFigura.dibujar(); else if (unaFigura.getClass() == Poligono.class) (Poligono)unaFigura.dibujar();
Diseo de jerarquas
Cuando construimos clases, una de las tareas a encarar es la construccin de jerarquas, por generalizaciones en la mayor parte de los casos, y en otros por especializaciones. Hay cuatro normas bsicas de la generalizacin: Al ir construyendo jerarquas, hay que poner la mayor parte de los atributos y mtodos lo ms arriba que se pueda, para evitar luego definiciones duplicadas. Si una porcin de cdigo se repite en muchas clases hermanas, habra que generar un mtodo y ponerlo en la clase base. En forma ms genrica, pero teniendo ms cuidado, se puede generar un ancestro de todas las clases que tengan cdigo en comn, auque esto slo es recomendable si se puede establecer la relacin es un. Yendo a un extremo mayor an, se puede crear una clase base de dos clases semnticamente diferentes pero con responsabilidades similares. Esto suele llamarse varianza, y debe quedar bien documentado en el cdigo. Creemos que esta extrapolacin slo debe hacerse en condiciones excepcionales, y cuando se demuestre fehacientemente la ventaja de hacerlo.
Pero adems de las cuatro normas recin enunciadas, no hay que olvidar tres ms, a menudo no consideradas: Evitar generalizar todo lo que parezca generalizable de entrada. Como primera etapa, debemos resolver el problema que tenemos entre manos de la manera lo ms simple posible.
20
Una nueva clase descendiente debe aadir o redefinir un mtodo o agregar una nueva clusula al invariante. Si no es as, quiere decir que no es necesaria, y corremos el riesgo de complicar la jerarqua sin un fin prctico. Esto parece evidente, pero muchas veces uno fue tentado a separa clases entre varones y mujeres cuando simplemente podra usarse un atributo booleano en la clase persona. Las jerarquas deben ser un aporte para dominar la complejidad, no para complicarla. La herencia se debe usar siempre y cuando la relacin entre los dos conceptos sea permanente. Si bien es ms sencillo describir una jerarqua de lo general a lo particular, no siempre sta es la mejor manera de construirla: A menudo se encuentran clases y la jerarqua se va construyendo por demanda. Otras veces las generalizaciones van surgiendo de las clases concretas, al descubrir atributos o mtodos en comn. Cuando se especializan clases adquiridas se procede por especializacin.
21
Una mala idea es elevar una excepcin si no hay error. Por ejemplo en una bsqueda, si no se encontr el valor buscado. Cuando todo falle, lance una excepcin. Consejos al trabajar con excepciones: Capturar las excepciones en el primer nivel que se pueda. De este modo tendrn un sentido mayor para el mbito. Usar excepciones en constructores, sobre todo para indicar que ste no termin bien. Una implementacin de clase debera venir con las excepciones que puede disparar. Ponerlas en el mismo paquete. Cuando se produce una excepcin luego de capturar recursos, a veces debemos liberarlos. El recolector de basura se ocupar de la memoria. El resto los debe liberar el programador en el bloque finally. Liberar en orden inverso a la adquisicin.
Patrones de diseo
El patrn de diseo resuelve problemas de diseo.
22
El patrn de programacin es un algoritmo ya hecho y con nombre. Ejemplo: mtodos de ordenamiento y bsqueda con nombres especficos. Los patrones se utilizan para la aplicacin en distintos contextos, enseanza, comprensin de partes de un sistema, comunicacin con un vocabulario comn. Principios: Encapsular lo que vara. Preferir la composicin a la herencia. Programar usando interfaces, no implementaciones. Bajo acoplamiento en la interaccin entre objetos. Mantener las clases abiertas para extensin y cerradas para modificacin. Una sola responsabilidad por clase.
Un patrn de diseo es una solucin a un problema en un determinado contexto. Nos indican cmo utilizar clases y objetos de modo de adaptarlos a la resolucin de un problema. Se aplica a una sociedad de clases. Ventajas: Estructuras de diseo probadas previamente. Fcil interpretacin de colaboraciones ya conocidas. Completitud frente a las soluciones caseras. Implementacin directa sin anlisis y diseo complejos. Facilidad de separar los aspectos que cambian de los que no cambian, dando un mayor nivel de la abstraccin. Introducen un lenguaje comn para referirse a formas de construir software, lo que a su vez favorece la enseanza, el aprendizaje y el trabajo en grupos. Se suelen denominar antipatrones a los diseos que han arruinado proyectos. Se usan para saber qu es lo que no hay que hacer. Un patrn debe: Ser concreto Resolver problemas tcnicos Utilizarse en situaciones frecuentes Favorecer la reutilizacin No necesariamente poder ser traducido a cdigo, pues resuelve familias de problemas.
23
Un patrn se suele lograr luego de que varios diseos llevaron a uno en forma natural, no a la fuerza.
Caso I: Singleton
Lo que hace es definir una clase que slo admite una instancia.
Debimos crear un constructor para que el compilador no lo cree por defecto y, declararlo privado. Observamos que el atributo que tiene el valor fue declarado esttico, es decir, de clase. La clase EnteroUnico fue declarada final. El objeto unico se deber crear con una llamada al mtodo obtenerUnico, como sigue: EnteroUnico unico=obtenerUnico();
24
Faltara definir la excepcin ePoolVacio. En este caso, si el programador desea una coleccin de elementos debe hacerlo definiendo esa coleccin en su aplicacin y luego vinculando cada elemento. El problema que subsiste en esta solucin es que no se pueden liberar objetos y colocarlos nuevamente en el pool. Una solucin es implementar el pool con un arreglo de objetos acompaado de otro que sirve para determinar si el elemento est disponible para obtenerlo. Permite devolver alguna instancia (la posicin del vector) que ya no se utilizar.
25
Podemos pensar en un programa de dibujo de figuras geomtricas que permite agrupar figuras de modo tal que ese grupo se comporte como una nica figura. Los mtodos dibujar y colorear se podran aplicar a una figura simple o compuesta. Diagrama de clases:
26
Implementacin posible:
27
28
Un ejemplo prctico son las applets de Java. Para generar un applet, lo que se hace es crear una nueva clase descendiente de JApplet y redefinir el mtodo init. El mtodo plantilla es quien llama a otros mtodos, como el init de JApplet, que son los que hay que redefinir.
La idea es entonces definir un metodoPlantilla que invoque a otros mtodos, como a y b. metodoPlantilla no es redefinible, mientras que a y b son abstractos y deben redefinirse. La clase cliente slo define a y b, y una aplicacin puede llamar al metodoPlantilla para que ste los invoque. Implementacin:
El mtodo ordenar hace de mtodo plantilla. mayor es el mtodo que debe redefinirse.
29
Otro ejemplo: Arrays.sort(Comparable[]) donde se debe redefinir el compareTo() pero no mediante herencia.
No siempre es necesario que Fabrica sea una clase abstracta. En la clase Fabrica, el mtodo operacion1 va a tener una lnea que llame al mtodo creador de objetos como la que sigue:
30
unProducto=crear(); A su vez, FabricaConcreta1 implementar el mtodo crear de la siguiente forma: public ProductoConcreto1 crear(){ return new ProductoConcreto1(); } Y algo similar har la clase FabricaConcreta2. Casos en que se usa: La clase a ser instanciada puede cambiar. No es fcil redefinir el mtodo en el cual se crean los objetos. Fbrica abstracta es ms complejo. Su objetivo es el encapsulamiento de la creacin de familias de objetos. Supongamos que necesitamos crear un botn y un men para dos tipos de interfaces de usuarios grficas: Windows y Macintosh. Una posible solucin sera un cdigo como el que sigue: Boton b; if (interfaz == Windows) b=new BotonWindows(); if (interfaz == Macintosh) b=new BotonMacintosh(); La mejor solucin es juntar todos los mtodos creadores en una clase FabricaGUI y luego redefinirlos. Diagrama de clases:
31
Observamos que el patrn fbrica abstracta tambin decide en forma esttica su forma de crear objetos.
32
Implementacin:
33
Un invariante puede verse como una condicin que se debe cumplir en todo objeto antes y despus de cada llamada a un mtodo.
Observamos que el mtodo que hay que invocar para que se verifiquen los invariantes es el mover definido en FiguraAbstracta.
Caso X: Proxy
34
Proxy es una clase que hace de interfaz de otra. Es decir, los mtodos del Proxy simplemente reemplazan con el mismo nombre a mtodos de otro objeto que por alguna razn no es accedido directamente. La ventaje principal es que los clientes actan hablando con un intermediario como si lo hicieran con el verdadero objetivo, y descansando en este intermediario toda la complejidad de la comunicacin con el objetivo verdadero. Proxy remoto: suele servir como cach o copia local, evitando que haya que ir a buscar cada vez al objeto remoto. Proxy virtual: cuando no se crea el objeto meta sino hasta que sea realmente necesario. Proxy de proyeccin: para controlar el acceso al objetivo. Proxy de sincronizacin: para gestionar acceso de varios clientes al objetivo.
Estructura de clases:
35
Diagrama de clases:
El Mediador registra y maneja eventos, mientras los observadores son interfaces que reciben notificaciones de cambios de estado de los clientes. El Mediador es quien implemente las interfaces observadoras para recibir las notificaciones, as como la lgica de las respuestas, e interacta con los objetos clientes.
36
Debemos vincular la lista con la Visita que se va a aplicar. Una posibilidad simple sera que ListaConRecorrido implemente la interfaz Visita y defina los mtodos
37
aplicar y cumpleFiltro. Un tipo de lista siempre quedara atado a ser recorrido con el mismo filtro y aplicando la misma funcin a sus elementos.
38
Modelo pull: Sujeto no enva info; slo notifica. Observadores consultan luego lo que les interesa. Puede ser ineficiente. Bien desacoplado.
Modelo con eventos: Se registran observadores slo para ciertos eventos o temas (uno o ms). Es de gran utilidad en MVC. En general es aplicable a cualquier desarrollo de sistemas en capas. La idea del patrn Observador es separar dos objetos: uno que es observado y otro u otros que observan, de modo que los segundos pueden cambiar su estado y comportamiento en funcin de cambios en el primero. Esta implementacin define una clase Observable, que permite crear clases derivadas de objetos observados. Observable hace un seguimiento de una lista de objetos observadores que desean ser informados de cualquier cambio en el observado, y notifica con un mtodo denominado notifyObservers. Tambin define una interfaz Observer, que expone una sola funcin denominada update, llamada por el objeto observado cuando decide que es hora de notificar cambios. Es el objeto observado quien decide cmo y cundo hacer la actualizacin. Para ello, Observable tiene un atributo lgico protegido que indica que hubo un cambio digno de ser notificado: este atributo se accede con las funciones hasChanged y setChanged. Mtodos de Observer y Observable en Java:
39
Deben definirse una clase descendiente de Observable que, ante determinados cambios, invoque los mtodos setChanged y nofifyObservers. En general los mtodos de Observable no se redefinen. Tambin se deber construir una clase que implemente Observer, escribiendo el mtodo update.
40
interface Accion { void hacer(); void deshacer(); } En un editor de texto podramos tener una clase que representa la eliminacin de una lnea.
Lo que se hace es almacenar lo que luego hay que reponer. Cada orden guardar cosas diferentes, que le sirvan par restaurar el estado a la situacin anterior. Por lo tanto, bastara con guardar siempre en una variable general del estado de la aplicacin la ltima orden ejecutada, con un atributo como el que sigue: Accin ultimaOrden;
41
Lo que acabamos de hacer slo admite un nivel de deshacer. Si se quiere agregar ms niveles habr que usar una lista histrica, en vez de guardar solamente la ltima orden enviada por el usuario, con una estructura de datos que permita hacer esto. Como consecuencia, la implementacin de deshacer y rehacer ser algo como:
42
43
44
45
46
Luego, para instanciar un sedn con techo corredizo y aire acondicionado, por ejemplo, se har: Componente a = new TechoCorredizo(new AireAcondicionado(new Sedan())); La estructura bsica del patrn Decorador es:
47
Colecciones con elementos genricos, aunque sea restringidos por la jerarqua. Gestin automtica de memoria y recoleccin de basura. Manejo de excepciones basado en clases. Manejo de concurrencia basado en clases para los procesos o hilos. Manejo de persistencia.
Conceptos de desarrollo de software antes y despus de la orientacin a objetos Ciclo de vida tradicional del software
El ciclo de vida tradicional, tambin llamado en cascada, se basa en ir cumpliendo una serie de etapas, cada una separada de las otras, de modo tal que recin se empieza una etapa cuando se termin la anterior. Cada etapa es efectuada por un grupo de personas especializadas en esa tarea, y una vez terminada la misma, se genera una serie de documentos que tomarn como entrada los trabajadores de la siguiente etapa. Ha habido muchas definiciones de las etapas del desarrollo en cascada, pero podemos esquematizarlas de la siguiente forma: Requerimientos: qu hay que hacer, y si es necesario hacer algo y por qu, con definicin de la frontera del sistema para determinar qu queda dentro del mismo y qu fuera. Se basa en entrevistas con los futuros usuarios. Anlisis: propuesta de solucin a los requerimientos, independientemente de la tecnologa y postergando toda referencia a detalles tcnicos. Diseo: cmo hacer lo que se estableci en el anlisis; en otras palabras, fijar la arquitectura global, las clases necesarias, tipo de persistencia, etc. Implantacin: llevar el diseo a cdigo ejecutable, crear las bases de datos, etc. Se suele incluir el despliegue del producto sobre el hardware. Pruebas y depuraciones: comprobar que lo implementado cumpla con los requerimientos iniciales y corregirlo en caso contrario. Mantenimiento post entrega: incluye correccin de errores, evolucin por cambio de requerimientos y preservacin para mantenerlo operable, una vez que el sistema se encuentra en produccin. Muerte del proyecto: se produce por obsolescencia, porque se termina el sistema y no es necesario agregarle ms nada, o cuando es muy caro de mantener. Diagrama de actividades del ciclo en cascada, sin mantenimiento:
48
El ciclo de vida en cascada tiene varias desventajas que hicieron que se lo fuera ajustando: Impide comenzar una etapa hasta que la anterior no est totalmente concluida, retrasando todo el proceso. Cuesta mucho cambiar algo sobre una etapa ya terminada, o se hace a costa de gran cantidad de burocracia y documentacin. A menudo se intentan soluciones locales, que tratan de remediar en el diseo lo que viene mal del anlisis o en la implementacin lo que viene mal del diseo. Recin luego de la implantacin se prueba el sistema. Por lo tanto, cuando surjan los inevitables errores, habr que comenzar a analizar en qu etapa se produjeron, y a partir de all modificar lo que sea necesario. El usuario final recin ve el sistema una vez que est terminando, por lo que generalmente se siente poco consustanciado con el desarrollo y no puede advertir errores de concepcin hasta la entrega total. Esto lleva a una serie de consecuencias negativas del uso de las metodologas estructuradas que se pueden resumir as: Entrega de productos que no satisfacen los deseos de los usuarios y que no pueden usarse con facilidad. Imposibilidad de poder responder con rapidez y de manera efectiva a los cambios de requerimientos. Demora en los proyectos novedosos.
49
Desarrollo incremental
La visin orientada a objetos plantea hacer requerimientos, anlisis, diseo, implantacin y prueba, en forma iterativa. Esta modalidad se denomina desarrollo incremental o en espiral. Las ventajas son:
Aumenta el compromiso de los usuarios al poder mostrarles versiones parciales (cascadas parciales). Los miembros del equipo de trabajo ven que se cumplen metas parciales y trabajan ms tranquilos aumentando la productividad. Permite hacer frente a cambios de requerimientos. Los errores aparecen antes, en las pruebas de cada iteracin. Esto reduce el riesgo y evite la carga emocional negativa que provoca el testeo al final del desarrollo. Hay ms continuidad entre las fases del desarrollo, de modo que una persona puede participar en varias de ellas. Esto implica que en las metodologas incrementales no se utilizan los mismos roles profesionales de los mtodos estructurados. Sin embargo, surgen nuevos roles, como lo s de arquitecto e integrador.
50
51
52
Lista de parmetros larga: Crear clases para los parmetros. Eliminar el parmetro y agregar una llamada a mtodo. Cambios divergentes: Separar las clases cuya necesidad de cambio tenga frecuencias distintas o provenga de necesidades diferentes. Shotgun surgery: Es lo opuesto a lo anterior. Cuando cada cambio me obliga a tocar muchas clases. Mover atributos o mtodos para crear una nica clase. Envidia de caractersticas: Cuando una clase se la pasa llamando a mtodos de otras clases. Poner los mtodos en las clases que los usan. Clases sin comportamiento: Pueden provenir de refactorizaciones anteriores. Pueden existir, pero no es bueno. Ifs y switchs abundantes: Herencia y polimorfismo. Patrones de estado y estrategia. Otras soluciones de catlogo. Jerarquas paralelas: Juntar clases. Herencia especulativa: Colapsar la jerarqua. Clases que son alternativas pero tienen interfaces diferentes: Renombrar mtodos y otras ms complicadas. Flexibilidad: La flexibilidad oscurece el cdigo y agrega complejidad. En general se flexibiliza segn lo que se espera que cambie. Es el enfoque de los patrones de diseo.
53
inaceptablemente pesadas para sistemas pequeos o medianos. En este grupo destaca el Proceso Unificado de Desarrollo de Software (PUDS o PUD). 2. Los mtodos giles (tambin evolutivos o adaptables), que permiten organizar desarrollos medianos sin caer en burocracias paralizantes. Pueden verse incluso como una alternativa a carecer de metodologa (o metodologa de codifica y corrige), que es lo que suele ocurrir cuando se descarga un proceso muy pesado. En este grupo destaca, como el ms conocido, Extreme Programming (XP). Lo fundamental es entender que no todas las metodologas sirven para cualquier proyecto, ni hay una sola que se pueda aplicar a todos.
54
de anlisis y casi nulo de implementacin y pruebas, mientras que en las finales ser lo contrario. Las fases del Proceso son: Fase de Inicio: planifica el proyecto, se estudia su factibilidad y se delimita su alcance. Se estudian los casos de usos con los usuarios y construyen prototipos para validar conceptos. Los objetivos del hito de finalizacin son: o Haber definido los objetivos del sistema. o Tener una idea aproximada del costo. o Establecer la factibilidad del proyecto (si conviene proseguir). o Obtener el modelo de dominio, que indique cmo se relacionan los diferentes conceptos. Qu hacer: Planificar el proyecto. Estudiar factibilidad. Delimitar alcance. No suele ser una fase iterativa.
Fase de Elaboracin: se establece la arquitectura y se analizan los riesgos mayores. Se hacen las pruebas que se correspondan con el diseo e implementacin. Se exploran escenarios y arquitecturas con los usuarios. Los objetivos del hito son: o Haber acotado los riesgos. o Tener definida la arquitectura bsica y el plan de iteraciones de construccin, indicando qu casos de uso se realizan en qu iteraciones. Empezar por los prioritarios para el cliente y los de mayor riesgo. Qu hacer: Establecer las arquitecturas. Analizar los riesgos mayores. Puede ser una fase iterativa.
Fase de Construccin: Se desarrolla un producto completo que est listo para ser utilizado como versin beta (es el objetivo final del hito). Es la fase iterativa por excelencia. Para reducir el riesgo funcional, cada iteracin debe ser un miniproyecto que debe terminar con una entrega al usuario y pruebas de sistema. Se deben terminar los requisitos y el anlisis que reste y se completar el grueso del diseo e implementacin, as como sus pruebas. Es decir que involucra al anlisis, el
55
diseo y la implementacin. Se pueden hacer cambios de arquitectura. Se debe ir ajustando la planificacin de las iteraciones. Se van ensamblando partes ya probadas sobre un cdigo tambin probado. Fase de Transicin: Es la fase en que el producto se despliega para ser utilizado. Aqu comienza una serie de puestas a punto y adaptaciones a necesidades no previstas de los usuarios que surjan de las pruebas beta. El objetivo del hito final es el lanzamiento del producto. No se aaden funciones nuevas pero se desarrolla para optimizar y depurar. Se hacen despliegues graduales en las etapas anteriores.
El Proceso parte de un modelo de casos de uso. Las iteraciones se hacen implementando casos de uso en forma completa. Y las pruebas se hacen tambin verificando las especificaciones de casos de uso. Por eso, los casos de uso se capturan y definen en requisitos, se realizan en anlisis, diseo e implementacin y se verifica que se satisfagan en las pruebas. En todas las etapas del desarrollo puede decidirse no conveniente seguir adelante con el mismo ya que el sistema no dara resultados esperados por el precio esperado. Esta tarea se suele denominar estudio de factibilidad.
56
Mtodos giles
Son mtodos no predecibles ya que son muy cambiantes en lo que respecta a requerimientos. Los clientes pueden decidir a ltimo momento que un requerimiento no es ms tenido en cuenta o que el software necesitara de otros requerimientos para satisfacer sus necesidades, por lo tanto es un mtodo cambiante de requerimientos. Se adaptan a cada desarrollo. Muy comunes en el software. No es para cualquier cliente ni para cualquier informtico. El diseo y la programacin van muy acoplados. No son compatibles con tiempos, alcances o presupuestos fijos. Un ejemplo de estas metodologas giles es Extreme Programming (XP).
57
Extreme Programming
Lleva al extremo las buenas prcticas. Los objetivos son bajar el riesgo, permitir cambios de especificaciones durante el desarrollo, favorecer la comunicacin con el cliente y que la inversin crezca gradualmente. Mximas: Como probar programas es bueno, se hacen pruebas unitarias y funcionales todo el tiempo, al punto que el desarrollo es dirigido por las pruebas, y stas se disean antes de codificar. Como hacer pruebas de integracin es importante, la integracin sigue inmediatamente a las pruebas unitarias. La integracin frecuente permite que no sea cada vez ms complicado integrar cdigo de varias fuentes. Como los diseos de software son cambiantes, el diseo del sistema evoluciona junto con la programacin, y lo hacen los propios programadores. Como revisar la calidad del cdigo es recomendable, se revisa cdigo todo el tiempo y se hacen refactorizaciones, que implican cambios de diseo para hacerlo ms simple, pero sin cambiar funcionalidad. Como los estndares de codificacin permiten una mejor comunicacin y reducen los errores, se fijan estndares precisos y estrictos. Como es bueno que el sistema sea simple, se busca la simplicidad siempre, diseando slo lo que se necesita en el momento. Este tal vez sea el principio fundamental y ms controvertido de XP. Como los requerimientos de arquitectura pueden ser cambiantes, la arquitectura se refina constantemente. Como el desarrollo incremental es positivo, se hacen iteraciones lo ms cortas que sea posible: se disea una pequea porcin, se la codifica y se la prueba. La idea es que dentro de cada iteracin nos debemos preocupar de lo que estamos haciendo, sin hacer nada por adelantado o pensando en futuras iteraciones. Se opera sobre el alcance como variable de ajuste, como en las otras metodologas giles. Como es muy frecuente que un proyecto de desarrollo se suspenda en un determinado momento por falta de presupuesto, se implementa primero lo que tiene mayor valor para el cliente. De ese modo, lo que queda sin desarrollar es siempre menos importante. La primera iteracin debe llegar a implementar un esqueleto del sistema, con una serie de funcionalidades bsicas.
58
Como es importante tener una comunicacin frecuente con el cliente, siempre debe haber un cliente acompaando el desarrollo. El cliente es fundamental para escribir pruebas funcionales y priorizar tareas. Como dos cabezas piensan ms que una, y como refuerzo de las prcticas anteriores, los programadores trabajan de a dos: uno escribe, el otro piensa en mayor escala, buscando simplicidad, errores y formas alternativas de solucin del problema. Las parejas pueden intercambiarse a lo largo del desarrollo, y dentro de cada pareja los roles van cambiando a lo largo de cada tarea a desarrollar. De todas maneras, cada pareja es responsable de una tarea, y no supone que haya intercambios hasta no terminarla. Este es el aspecto ms mencionado y a la vez menos conocido de XP. El aspecto que ms resistencias genera, y que es central en XP, es la simplicidad llevada al extremo. La recomendacin de XP es que cualquier cdigo duplicado debe refactorizarse de modo de eliminar duplicaciones. Afirma que si una clase, un mtodo o cualquier porcin de cdigo no sirven para el sistema actual, se debe eliminar. No obstante, XP afirma que hay que eliminar toda la flexibilidad que no demuestre su utilidad en lo inmediato, evitando resolver hoy los problemas de maana. Razones de XP: Se evita agregar complejidad que luego dificulta las refactorizaciones, la comunicacin y las depuraciones. Se evita implementar lo que no sabe si se va a usar (y en el 80% no se usa). Se mantiene baja la inversin inicial en el proyecto, de modo que si ste se abandona o se trunca no habr costado tanto. Y aunque estos extremos no ocurran, la inversin inicial es la que tiene mayor costo financiero, por lo que mantenerla baja es siempre una buena poltica. Mejora la eficiencia de ejecucin del sistema, debido a que el cdigo ejecutable permanece ms chico. XP no es aplicable: A proyectos que, por razones organizacionales o presupuestarias, necesiten especificaciones precisas desde el comienzo. A equipos de trabajo con ms de 20 programadores (en nmero ideal es 10). A equipos de trabajo que deben trabajar separados, algo muy en boga de nuestros tiempos. Cuando la tecnologa es un impedimento por los altos tiempos de compilacin, prueba o integracin.
59
Una introduccin a las pruebas en programacin orientada a objetos Las pruebas en las metodologas de desarrollo incremental
Los mtodos incrementales de integracin y prueba evitan el colapso de los sistemas en su ltima fase de implementacin, ya que permiten probar temprano las funcionalidades cruciales de los mismos. Podrn ver el progreso del sistema desde su estado ms rudimentario hasta su eventual completitud. Las metodologas ms modernas hacen un desarrollo iterativo en todas las fases. En este sentido, las pruebas son un proceso continuo que comienza en la primera iteracin. Las pruebas unitarias se pueden aplicar a clases, bloques y paquetes. A veces es mejor probar paquetes enteros, ya que las clases en un paquete suelen interactuar bastante o tambin testear la herencia y el polimorfismo y el ciclo de vida del objeto. Pueden usar aserciones. Las pruebas de integracin se aplican a bloques, paquetes, casos de uso y subsistemas. Si utilizamos prototipos, cada prototipo es como un mini sistema, por lo que en su tramo final se le deben efectuar pruebas de sistema y de aceptacin. El Proceso Unificado recomienda probar casos de uso. Estos casos se llaman casos de prueba y suele haber una relacin uno a uno con los casos de uso de las etapas de requerimientos y anlisis. Las pruebas de caja negra se pueden preparar desde el anlisis. Las de caja blanca se pueden implementar mientras se disea. Las pruebas de sistema y aceptacin se realizan en la etapa de transicin. El Proceso Unificado pone especial nfasis en la planificacin de las pruebas de cada iteracin.
60
61
62
Documentar en el propio cdigo facilita mantener la documentacin actualizada. Adems, el hecho de que la documentacin est cerca de lo que se documenta siempre una ventaja. A esto se lo llama documentacin interna. Recomendaciones: No usar comentarios como remedio para el cdigo poco claro. Ante todo, cdigo debe ser bien legible. Los comentarios muy abundantes slo deben ir como prlogos de secciones muy crticas, poco claras, avisos para el mantenimiento y efectos colaterales locales. Evitar los comentarios del tipo no borrar, que en general acompaan una lnea de cdigo ininteligible. Con el tiempo nadie sabr por qu no hay que borrar la lnea, y el solo hecho de figurar el comentario indica un cdigo oscuro, mal escrito o una pobre documentacin.
El caso de javadoc
El programa javadoc, que toma algunos de los comentarios que se colocan en el cdigo con marcas especiales y construye un archivo HTML con clases, mtodos y la documentacin que corresponde. Se inscribe en comentarios que empiezan con /** y terminan con el habitual */. Se pueden escribir comandos precedidos de @. Se debe poner la documentacin inmediatamente antes de la declaracin respectiva. javadoc procesar la documentacin que se escriba para atributos y mtodos pblicos y protegidos, sin emitir nada para los privados y de paquete. Slo deberan omitirse los formatos de ttulos <h1> y <hr>. Ej: /** <h2> La clase que sigue es muy importante: </h2>*/ Cuando se quiere indicar una referencia a otra clase se puede usar el comando @see: @see nombre-de-clase @see nombre-de-clase-con-todos-sus-calificadores @see nombre-de-clase-con-todos-sus-calificadores#nombre-mtodo De este modo, aparecer un vnculo del tipo vase tambin.
63
La informacin de versin se puede indicar con @version: @version informacin-de-versin La informacin a colocar puede ser cualquiera que nos parezca interesante. Con el comando @author se puede poner tambin cualquier informacin sobre el autor o autores de una clase: @author informacin-del-autor Con el comando @since se puede informar desde cundo o qu versin se encuentra vigente una determinada capacidad de la clase. Para documentar parmetros, valores devueltos y excepciones de un mtodo se usan los comandos @param, @return y @throws: @param nombre-de-parmetro descripcin @return descripcin @throws clase-de-excepcin-con-sus-calificadores descripcin Igualmente se pueden incluir en la documentacin avisos de supresin de una determinada caracterstica en versiones futuras, de modo de que su uso vaya siendo abandonado, con el comando @deprecated, que provoca un aviso del compilador.
Estndares de nomenclatura
Existen estndares para entender mejor un cdigo que ya fue escrito, para que a futuro se entienda nuestro cdigo por otras personas o por nosotros mismos. Cada lenguaje tiene un estndar de nomenclatura especfico, pero a la vez puede utilizarse cualquiera que sea ms conveniente.
Persistencia
Introduccin Persistencia y objetos persistentes
Llamamos persistencia a la capacidad de un objeto de trascender el tiempo o el espacio. En la programacin tradicional se supla con la entrada y salida de datos.
64
Permite que un objeto pueda ser usado en diferentes momentos a lo largo del tiempo, por el mismo programa o por otros, as como en diferentes instalaciones de hardware en el mismo momento. Guardando el estado de un objeto y poder enviarlo por una red. Un objeto persistente es aqul que conserva su estado en un medio de almacenamiento permanente, pudiendo ser reconstruido de modo tal que se encuentre en el mismo estado en que se lo guard. Al objeto no persistente lo llamamos efmero. Cuando se trate de guardar el estado completo de una aplicacin en un determinado momento, la mejor solucin es almacenar todo el estado en un solo objeto y luego guardarlo. De este modo, la persistencia sirve tambin para guardar estados de objetos complejos. Separacin de identidad y estado. En UML, el que una clase sea persistente se indica mediante un valor etiquetado denominado persistent, como en el ejemplo que sigue:
El objetivo principal de separar un sistema en capas es el de permitir cambios de implementacin en alguna de las mismas sin afectar a otras.
65
Permitir que un mismo sistema informtico pueda almacenar sus datos en diferentes tipos de bases de datos o archivos, o exportar hacia computadoras que estn trabajando con otra plataforma.
Normas de la persistencia
Hay tres principios de la persistencia: De la ortogonalidad del tipo de datos: para todo tipo debe haber persistencia. De la identificacin persistente: el diseo de la persistencia no debe depender del universo conceptual del sistema. De la persistencia independiente: los programas no deben variar segn la longevidad de la informacin que manipulan.
66
El archivo System.out que venimos utilizando para las salidas por consola es una instancia de la clase PrintStream. Dicha clase tiene un mtodo print y otro println, siendo el segundo igual al primero, salvo por el hecho de que inserta un carcter de fin de lnea luego de imprimir. Estos mtodos estn sobrecargados para todos los tipos primitivos y para String, pudiendo utilizarse tambin automticamente por cualquier clase que redefina el mtodo toString de Object. Igualmente hay otro archivo estndar de la clase PrintStream, el flujo de salida de errores System.err. La que sigue es la jerarqua de clases derivadas de InputStream:
El siguiente ejemplo muestra un fragmento de cdigo que lee un archivo por lneas y lo muestra por consola:
67
Otra caracterstica adicional es el paquete java.nio (cambio en versin 1.4), que coexiste con java.io. Mejor desempeo. Mejor soporte de redes. ByteBuffer tiene algunas facilidades, como mtodos para convertir los bytes en datos de tipos primitivos, llamados asCharBuffer, asIntBuffer, asDoubleBuffer, asLongBuffer, etc. Tambin provee vistas especiales, que si bien no modifican la estructura del ButeBuffer, le permiten mostrarse como de un tipo primitivo. Estas se implementan mediante las clases IntBuffer, LongBuffer, CharBuffer, DoubleBuffer, etc.
68
69
basta que alguna de las aplicaciones no est escrita en Java para que sea necesario hacer una descripcin bastante compleja de la forma de interpretar los datos serializados. Una solucin a este problema podra ser el uso de XML. Dada la estructura de XML, se podran almacenar objetos compuestos sin mucho esfuerzo, garantizado la posibilidad de ser usados en varios lenguajes. Con APIs especiales en cada lenguaje: SAX, DOM, JDOM, dom4j. Multiplataforma y multilenguaje. En este contexto, podramos tener un mtodo para cada clase que serialice objetos a fragmentos de cdigo XML, y otro que haga lo inverso. Por ejemplo, supongamos que la informacin de un empleado se guarda en un objeto cuyos atributos son nmero de legajo, apellido, nombre y fecha de nacimiento, siendo sta ltima a su vez un objeto formado por da, mes y ao. Su representacin en XML podra ser:
Serializacin en Java
Java tiene una interfaz Serializable, en el paquete java.io, de modo que toda clase que la implemente va a poder transformar sus objetos en cadenas de bytes y viceversa. Implementarla permite al compilador generar informacin de serializacin. Evita el lanzamiento de NotSerializableException. Permite usar ObjectOutputStream y ObjectInputStream para leer y escribir. Slo faltar crear un objeto de clase OutputStream, envolverlo en un ObjectOutputStream e invocar al mtodo writeObject.
70
El proceso inverso tambin es muy simple. Dentro de la misma clase se podr implementar un mtodo hidratar. public Fraccion hidratar (String archivo) throws IOException, ClassNotFoundException{ ObjectInputStream entrada = new ObjectInputStream(new FileInputStream(archivo)); return (Fraccion)entrada.readObject(); } Observamos que ni siquiera es necesario invocar a un constructor para hidratar un objeto (en realidad, el constructor es llamado por el mtodo readObject). El hecho de tener que declarar que se lanzan las excepciones IOException y ClassNotFoundException se debe a que son arrojadas por los mtodos de entrada y salida, y no se las puede ignorar. En principio, esta solucin no serializa los objetos contenidos, pero si estos objetos internos pertenecen a clases que implementan Serializable, la persistencia es isomrfica (si las clases ancestros tambin la implementan). La interfaz Serializable asegura que se serialicen todos los atributos no declarados transient ni static, as como todos los objetos contenidos. Si se intenta serializar un objeto no serializable se va a obtener la excepcin NotSerializableException. Incluso se puede usar la reflexin de Java para determinar la clase del objeto que est almacenado en un archivo. ObjectInputStream entrada = new ObjectInputStream(new FileInputStream(datos.dat)); Object o = entrada.readObject(); if (o.getClass() == Fraccion.class)
71
Fraccion z = (Fraccion) o; De esta forma se garantiza la persistencia polimrfica. La serializacin de Java asegura tambin que se copien los atributos privados. Sin embardo si no se querra serializar todo el objeto lo que se puede hacer es declarar un atributo con el modificador transient: Private transient nombreUsuario; Si se desea una funcionalidad ms controlada por el programador se puede implementar la interfaz Externalizable, derivada Serializable, que expone dos mtodos adicionales writeExternal y readExternal. Un ejemplo de tarea para la que puede servir Externalizable es la de evitar que se serialicen ciertos atributos.
72
El siguiente paso fue la incorporacin de interfaces (front-ends) orientadas a objetos a las bases de datos relacionales. Esta solucin, que es an la que ms se utiliza, se la llama tambin de bases de datos relacionales basadas en objetos. En este caso hay un proceso que traduce los objetos al modelo relacional tradicional, que va a ser parte de la capa de acceso a datos. Por lo tanto los objetos deben ser interceptados antes de ser almacenados y traducidos de formato, y al recuperarlos se hace el procedimiento inverso. Se trata de una solucin mixta que mantiene el paradigma relacional en la capa de acceso a datos y el de objetos en la lgica de la aplicacin. Entre sus ventajas est la simplicidad de implementacin. Pero el software de traduccin est disociado del universo del sistema. Esta solucin deja al descubierto la dificultad de representar un objeto complejo en el modelo relacional.
73
Las bases de datos relacionales funcionan bien con grandes volmenes de informacin, pero con una estructura regular de datos (registros similares) y con tipos de datos sencillos y predefinidos, por eso es que uno de los primeros caminos en la bsqueda de un cambio fue introducir los BLOBs. Adems, el modelo relacional identifica cada objeto por el valor que contiene, mientas el modelo orientado a objetos puede perfectamente trabajar con dos objetos distintos cuyos estados sean los mismos (esta es la caracterstica de la identidad de los objetos). Se ha definido que una BDOO debe proveer como mnimo: Persistencia. Control de acceso. Consultas basadas en valores de propiedades y no en la ubicacin. Restricciones semnticas. Soporte de transacciones. Soporte del encapsulamiento: acceso a las propiedades internas a travs de una interfaz definida. Definir una identidad (nica) de cada objeto que no dependa de su estado. Permitir las referencias entre objetos. Algunas de las BDOO ms conocidas son: Gemstone Objective/DB ObjectStore Ontos O2 Itasca Matisse Versant Poet Objectivity
Visin J2EE: Es la ms audaz. Propone que todo EJB de tipo CMP entity mantenga su estado en un repositorio permanente sin que el programador se deba preocupar de ello. Con base de datos relacionales o no. Crticas: Restricciones sobre el modelo de clases, dificultades de implementacin, bajo desempeo, aunque muy mejorada en Java EE 5.0. Frameworks de persistencia:
74
Se ocupan de hacer un mapeo del mundo de los objetos al mundo relacional. O/R-mapping. Generalmente trabajan con archivos XML que definen cmo se hace el mapeo. Muchas soluciones comerciales muy buenas. Ahorran mucho trabajo. A veces me evitan desarrollar la DAL. Casos: Hibernate, JDO, OJB, DataObjects. Si no son suficientes se pueden construir un propio framework.
75