Sei sulla pagina 1di 15

Programacin IV

Tema 5 Clases de Utilidad

Colecciones en los Lenguajes Orientados a Objetos


El trmino colecciones es utilizado para hacer referencia a datos estructurados en los cuales cada elemento tiene un significado similar, aunque su valor dependa de la posicin. Los ejemplos ms conocidos son los arreglos, las listas enlazadas, los rboles, y otros. Algo que hace tiles a las colecciones es que son objetos en los cuales se puede operar sobre un elemento en particular, sobre un conjunto de elementos seleccionados mediante un filtro o sobre la coleccin como conjunto. Tambin a veces se los llama contenedores, porque contienen otros objetos. Desde que empezaron a surgir lenguajes de programacin con cierto nivel de abstraccin de datos, se soportaron las colecciones en forma estndar. As, Fortran y Cobol manejaban arreglos, Pascal introdujo los conjuntos y varios lenguajes dieron facilidades para manejar estructuras dinmicas con la ayuda de punteros. Todo esto es previo a la orientacin a objetos. . El problema principal de este enfoque tiene que ver con la dificultad de la reutilizacin de cdigo cuando semnticamente es totalmente genrico. Por ejemplo, si en Pascal se desarrolla un procedimiento que ordena un vector de enteros en forma creciente, habr que reescribir el mdulo si se desea trabajar con elementos reales o cadenas de caracteres. Ada fue el primer lenguaje que encar esta problemtica, tambin antes de la adopcin de la POO. Este lenguaje, pionero en tantos aspectos, implement el concepto de tipo genrico, que admita declarar un tipo de coleccin, con todas sus operaciones, difiriendo la definicin del tipo del elemento hasta el momento de definir la variable instancia de la coleccin. Algo parecido implement luego C++ con sus clases parametrizadas, ya en el marco de la POO. Todos los lenguajes de POO manejan arreglos en la forma tradicional, con la definicin de una estructura de datos indexada, de tamao fijo y con elementos del mismo tipo. Esta estructura, que es de las ms antiguas de la programacin, si bien es esttica y limitada, es muy eficiente. Tambin se proveen, en todos los lenguajes, colecciones dinmicas. Cada coleccin tiene una interfaz diferente y un comportamiento tambin diferente, adems de eficiencias diferentes para las distintas operaciones. Por ejemplo, una lista encadenada es muy eficiente para insertar y eliminar elementos, adems de para ser recorrida secuencialmente, pero es ms lento acceder a un elemento individual que en el caso de un arreglo. Todas las colecciones proveen alguna forma de agregar y obtener elementos. Pero lo ms interesante de la POO en su relacin con las colecciones es la posibilidad de trabajar con datos estructurados con elementos de varios tipos, lo cual favorece la aplicacin del polimorfismo y la reutilizacin, ste ltimo uno de los objetivos ms fuertes de la orientacin a objetos.

Tipos de estructuras de datos


Una coleccin puede ser finita si se conoce su tamao, ordenada si se sabe su secuencia y homognea si todos los elementos son del mismo tipo. Este es el caso de un objeto de tipo Arrays en java. Tambin existen estructuras de datos de tipo dinmicas, es decir, colecciones de elementos (tambin llamados nodos), que son registros con la particularidad de crecer a medida que se ejecuta un programa. Al contrario de los arreglos (estructura de datos estticas) que slo pueden almacenar un nmero fijo de elementos, una estructura de datos dinmica se ampla y se contrae durante la ejecucin del programa. Dicho de otra manera, este tipo de estructuras no reserva una zona esttica (fija) de memoria para su almacenamiento, sino que el espacio ocupado crece o decrece a medida que evoluciona (se ejecuta) la estructura y su programa correspondiente. Las estructuras de datos dinmicas se pueden dividir en dos grandes grupos: Lineales: Pilas, Colas, Listas No Lineales: rboles, Grafos Las estructuras de datos dinmicas son extremadamente flexibles, de all que son muy utilizadas para el almacenamiento de datos que cambian constantemente.

Licenciatura en Sistemas de Informacin

Prof. Cristina Greiner

Programacin IV

Tema 5

Colecciones en Java
En la versin 1.2 de Java (J2SE) se introdujo el Java Collections Framework (JCF) o estructura de colecciones de Java. Es un conjunto de clases e interfaces que mejoran notablemente las capacidades del lenguaje respecto a estructuras de datos. Adems, constituyen un excelente ejemplo de aplicacin de los conceptos propios de la programacin orientada a objetos. A travs del JCF se uniformiza la manera en que son manipulados grupos de objetos. Las caractersticas principales del JCF son: Interfases: Posee una serie de Interfases que permiten extender o generar Clases especficas para manipular objetos en forma grupal. Implementaciones: Proporciona una serie de implementaciones (Clases) concretas en las que se pueden almacenar objetos en forma grupal. Algoritmos: Ofrece una serie de mtodos estndar para manipular los objetos dentro de una implementacin, como ordenamiento o bsqueda. La estructura del JCF es la siguiente:

a) Interfaces de la Collection Frameworks

b) Jerarqua de clases de la Collection Frameworks

Las interfaces tienen dos races en la jerarqua: Collection y Map. Existe una pequea diferencia de funcionamiento entre ambas. Bsicamente se puede decir que una Collection trabaja sobre conjuntos de elementos singulares mientras que un Map trabaja sobre pares de valores, por lo tanto tambin existen pequeas diferencias entre los mtodos necesarios por unas y otras. En la figura a), en letra cursiva se indican las clases que implementan las correspondientes interfaces. Por ejemplo, hay dos clases que implementan la interface Map: HashMap y Hashtable. Existen clases que son llamadas clases histricas, (versiones previas a la 1.2). Se denotan en la figura con la letra h entre parntesis. Aunque dichas clases se han mantenido por motivos de compatibilidad, sus mtodos no siguen las reglas del diseo general del JCF. Se recomienda utilizar las nuevas clases. En el diseo de la JCF las interfaces son muy importantes porque son ellas las que determinan las capacidades de las clases que las implementan. Dos clases que implementan la misma interface se pueden utilizar exactamente de la misma forma. Por ejemplo, las clases ArrayList y LinkedList disponen exactamente de los mismos mtodos y se pueden utilizar de la misma forma. La diferencia est en la implementacin: mientras que ArrayList almacena los objetos en un array, la clase LinkedList los almacena en una lista vinculada. La primera ser ms eficiente para acceder a un elemento arbitrario, mientras que la segunda ser ms flexible si se desea borrar e insertar elementos. La figura b) muestra la jerarqua de clases de la JCF. En este caso, la jerarqua de clases es menos importante desde el punto de vista del usuario que la jerarqua de interfaces. En dicha figura se muestran con fondo blanco las clases abstractas, y con fondo gris claro las clases de las que se pueden crear objetos. Las clases Collections y Arrays son un poco especiales: no son abstract, pero no tienen constructores pblicos con los cuales crear objetos. Fundamentalmente contienen mtodos static para realizar ciertas operaciones de utilidad: ordenar, buscar, introducir ciertas caractersticas en objetos de otras clases, etc.

Licenciatura en Sistemas de Informacin

Prof. Cristina Greiner

Programacin IV
1. La jerarqua de interfaz Collection

Tema 5

Esta interfaz define una serie de mtodos, para tratar una coleccin genrica de elementos, que sern los que el resto de interfaces o clases deben implementar. Los mtodos tienen un nombre bastante intuitivo que indica fcilmente la operacin que realizan. Es posible aadir un elemento (add) o aadir varios elementos (addAll), as como eliminarlos (remove/removeAll). Tambin es posible consultar si uno o ms elementos se encuentran en el conjunto de datos (contains/containsAll) as como ver el nmero de elementos de que dispone (size) o verificar si la coleccin esta vaca (isEmpty). Tambin es posible eliminar todos los elementos (clear) y obtener una vista especial (iterator) para recorrer la coleccin de datos. El mtodo retainAll elimina del conjunto de datos todos los elementos excepto los especificados. Collection es una interfaz, por lo tanto no proporciona ninguna implementacin concreta. La base para las clases concretas se encuentra en la clase AbstractCollection. Esta clase proporciona implementaciones por defecto para la gran mayora de los mtodos definidos por la interfaz de Collection. Por lo tanto si se desea crear una estructura de datos existen dos posibilidades: a. Crear una clase que implemente todos los mtodos de Collection. b. Crear una clase que extienda a AbstractCollection y proporcionar la implementacin slo para los mtodos necesarios, como por ejemplo size(). 1.1. La interfaz List Define una coleccin de datos ordenados permitiendo elementos duplicados. Aade operaciones a nivel de ndice de los elementos as como la posibilidad de trabajar con una parte de la lista. Tiene operaciones para aadir uno o varios elementos (add/addAll), para obtener un elemento determinado (get) a travs del ndice, para obtener el ndice de un elemento (indexOf/lastIndexOf) o para modificar o borrar un elemento (remove/modify). Los mtodos que permiten trabajar con una parte de la lista son: ListIterator listIterator() ListIterator listIterator(int comienzo) List sublist(int inicio, int fin) Los dos primeros mtodos devuelven una vista de la coleccin de datos (Iterator) que permite recorrer sus elementos. La interfaz ListIterator extiende a Iterator, permitiendo realizar recorridos bidireccionales as como aadir o modificar elementos de la coleccin a la que representa. List es tambin una interfaz, por lo que solamente define el conjunto de mtodos que las implementaciones concretas deben proporcionar. Implementaciones: ArrayList y LinkedList 1.1.1. La clase ArrayList Deriva de la clase AbstractList. Internamente ArrayList representa la estructura de datos utilizando un array de objetos. Este array comienza con un tamao determinado que se puede especificar en el constructor y va creciendo dinmicamente a medida que se aaden elementos. En los casos en que se conoce a priori el tamao que va a tener el ArrayList es siempre recomendable utilizar el constructor ArrayList(int size) que crear un array con la capacidad especificada. Otro factor muy importante ligado al almacenamiento de elementos en un array es que al insertar un elemento hay que mover todos los elementos que se encontraban a partir de la posicin en la que se insertar, una posicin ms a la derecha. De esto se deduce que las inserciones al inicio son ms costosas que las inserciones al final del array. Al estar internamente los datos en un array el acceso indexado a elementos de la estructura es muy rpido, siendo ste el fuerte del ArrayList. Por lo tanto, si la aplicacin tendr un acceso indexado a los datos, la estructura a elegir es claramente ArrayList. Sin embargo si la aplicacin va a tener una gran cantidad de inserciones o borrados en diferentes zonas de la estructura entonces quizs sera ms conveniente la siguiente clase.

Licenciatura en Sistemas de Informacin

Prof. Cristina Greiner

Programacin IV

Tema 5

1.1.2. La clase LinkedList Esta lista est implementada utilizando una lista de nodos doblemente enlazada. En este caso para acceder a un elemento determinado se deber recorrer todos los elementos previos de la lista, por consiguiente el rendimiento en acceso por ndice a elementos no es mejor que en un ArrayList. Por otra parte, el costo de eliminar o insertar un elemento en una determinada posicin se reduce al costo de buscar dicho elemento, siendo muy pequeo cuando estas operaciones se realizan al principio de la lista y algo mayor al realizarse al final. Con esta clase se evita el costo de mover datos o de tener que aumentar el tamao de la estructura, mientras que se pierde rendimiento realizando la bsqueda de los elementos. 1.2. La interfaz Set Esta interfaz extiende a la interfaz Collection y no aade ningn nuevo mtodo. Representa un conjunto de datos que no admiten duplicados. Por lo tanto si se aade un elemento a un conjunto y ese elemento ya se encontraba en su interior no se producir ningn cambio en la estructura de datos. Para determinar si un dato se encuentra o no en el conjunto, las implementaciones se basan en los mtodos equals() y hashCode() de la clase Object. Implementaciones: HashSet y TreeSet, con pequeas diferencias entre cada una de ellas. 1.2.1. La clase HashSet No permite duplicados pero s un nico elemento nulo. Implementa el conjunto de datos utilizando un tabla hash (HashMap). Los elementos dentro de la interfaz no estn ordenados y pueden variar su posicin a lo largo del tiempo. Esta clase ofrece un rendimiento similar para las operaciones bsicas (add, remove, size...), siempre y cuando la funcin de hash realice una dispersin correcta de los elementos. 1.2.2. La clase TreeSet Esta implementacin utiliza un TreeMap (rbol binario) para almacenar los objetos. Los objetos se guardan de una manera ordenada, en orden ascendente, segn el orden natural de los objetos o segn el orden del comparador que se le pase en el constructor. Esta clase es til cuando se desea recorrer los elementos del conjunto de una manera ordenada. En cuanto a rendimiento, esta clase proporciona un costo de log(n) en las operaciones bsicas (add/remove/contains). 1.3. La interfaz SortedSet Deriva del interfaz Set. Garantiza que el Iterator obtenido de la clase que lo implemente recorrer en sentido ascendente los elementos. Si bien la interfaz no puede imponer esta premisa la implementacin de la clase TreeSet si. 2. La jerarqua de interfaz Map Esta interfaz es la raz de otra jerarqua de interfaces. Define un conjunto de pares clave/valor, sin permitir claves duplicadas. Existen mtodos para introducir uno o ms pares clave-valor (put/putAll), para eliminar un elemento con una clave determinada o todos los elementos (clear/remove). Tambin posee mtodos para obtener un valor especfico segn la clave (get), mtodos para ver si existe una clave o un valor (containsKey/containsValue) y mtodos para consultar el tamao (size/isEmpty). Y por ltimo tiene un mtodo keySet que devuelve un conjunto de datos (Set) con todas las claves. Devuelve un conjunto ya que las claves son nicas. Como los valores no tienen por qu ser diferentes, el mtodo values devuelve una Collection. Implementaciones: HashMap y TreeMap

Licenciatura en Sistemas de Informacin

Prof. Cristina Greiner

Programacin IV

Tema 5

2.1. La clase HashMap Esta clase implementa la interfaz Map utilizando una tabla hash. Esta implementacin permite el valor null tanto como clave o valor. Al igual que en un HashSet (utiliza HashMap) esta clase no garantiza el orden de los elementos, ni siquiera que no puedan cambiar de orden por motivos de balanceo de carga. Esta clase garantiza un tiempo constante de acceso para las operaciones bsicas (get/put), siempre asumiendo que la funcin de hash realice una funcin correcta de los hashCode. 2.2. La clase TreeMap La implementacin de esta clase ordena los elementos por orden ascendente de clave, ya sea el orden natural de los objetos o el orden establecido por el comparador que se le pase en el constructor. Esta clase garantiza un coste de log(n) para las operaciones get, put y contains. 3. Interfaces de soporte 3.1. Iterator: sustituye a la interface Enumeration. Dispone de mtodos para recorrer una coleccin y para borrar elementos. 3.2. ListIterator: deriva de Iterator y permite recorrer lists en ambos sentidos. 3.3. Comparable: declara el mtodo compareTo() que permite ordenar las distintas colecciones segn un orden natural (String, Date, Integer, Double, ). 3.4. Comparator: declara el mtodo compare() y se utiliza en lugar de Comparable cuando se desea ordenar objetos no estndar. Por ejemplo, ordenar figuras geomtricas por el rea o el permetro. Es similar a Comparable, pero el usuario debe proporcionar la implementacin. Algoritmos y estructuras de datos La API de Collections no slo incluye las interfaces y las clases necesarias para crear y utilizar estructuras de datos en java sino que tambin incluye un conjunto de clases que tienen ya implementadas una serie de algoritmos para utilizar con los conjuntos de datos. 1. Algoritmos de ordenacin Tradicionalmente la ordenacin de datos ha sido y es una de las operaciones ms habituales sobre estructuras de datos y sobre conjuntos de datos en general. Con la inclusin del JCF muchos de los tipos de datos de Java pasaron a soportar implcitamente los algoritmos de ordenacin al implementar la interfaz Comparable. 1.1. La interfaz Comparable Esta interfaz se utiliza cuando los elementos de una de las clases tienen un orden determinado. Dado un conjunto de objetos, esta interfaz permitir ordenar esos objetos en un orden determinado. La interfaz Comparable define un nico mtodo: public int compareTo(Object o) Este compara la instancia actual de la clase que implemente la interfaz Comparable con un objeto pasado como parmetro. 1.2. La interfaz Comparator Define los siguientes mtodos: int compare(Object elemento1, Object elemento2) boolean equals(Object o) Permite realizar una ordenacin, en este caso, comparando los dos elementos pasados. El mtodo equals() en este caso se utiliza para ver cundo dos implementaciones de Comparator son iguales. Como curiosidad, la clase Collections (que es la que posee mtodos auxiliares de utilidad) tiene un mtodo llamado reverserOrder() que devuelve un comparador que ordenar cualquier coleccin de elementos en el orden inverso al que se hara normalmente. No olvidar que en la API Collections existen dos interfaces definidas que permiten mantener elementos de una manera ordenada. Estas son SortedSet y SortedMap y sus implementaciones concretas son TreeSet y TreeMap.

Licenciatura en Sistemas de Informacin

Prof. Cristina Greiner

Programacin IV

Tema 5

2. La clase Collections La clase Collections tiene un conjunto de mtodos de utilidad que permitirn realizar operaciones sobre las estructuras de datos. 2.1. Colecciones de datos inmutables En ocasiones, luego de haber creado una estructura de datos, se desea proteger su acceso para evitar inconsistencias. La clase Collections brinda esta posibilidad mediante seis mtodos. Por ejemplo : ..... Set nombres = new HashSet(); nombres.add(Rosa); nombres.add(Nuria); nombres = Collections.unmodifiableSet(nombres); nombres.add(Laura); La ltima llamada a add(), originar una excepcin UnsupportedOperationException en tiempo de ejecucin. 2.2. Algoritmos de ordenacin Existen dos interfaces que definen conjuntos y mapas de datos ordenados. Sin embargo, no existe ninguna interfaz que defina una lista ordenada. Para salvar ste y otros problemas, la clase Collections proporciona dos mtodos para listas de datos: void sort(List list) void sort(List list, Comparator c) El primer mtodo se utiliza cuando los elementos de la lista implementan la interfaz Comparable, y el segundo cuando se desea utilizar un comparador propio, o cuando no sea del agrado el funcionamiento del comparador por defecto. 2.3. Algoritmos de bsqueda Al utilizar el mtodo contains() sobre una lista para obtener un elemento, este mtodo asume que la lista no est ordenada, e ir buscndolo secuencialmente. Si previamente se ordena la lista, se puede obtener un gran aumento de rendimiento utilizando una bsqueda binaria. Existe un par de mtodos en la clase Collections para realizar esto: int binarySearch(List lista, Object clave) int binarySearch(List lista, Object clave, Comparator comparador) Como en la ordenacin, se utilizar una versin o la otra segn conveniencia. Si la lista no se encuentra ordenada los resultados son imprevisibles. Por otra parte, si la lista contiene varias veces el mismo elemento no habr ninguna garanta de cual es el que va a encontrar primero. 2.4. Manipulacin de elementos La clase Collections proporciona varios mtodos que permiten modificar los elementos de las estructuras de datos. Por ejemplo, se puede rellenar una lista con elementos (fill), copiar los elementos de una lista en otra diferente (copy), invertir el orden de los elementos de una lista (reverse) o permutar las posiciones de los elementos de una lista (shuffle).

especializados, como por ejemplo conjuntos constantes de un slo elemento (singleton) o lists con n copias del mismo elemento (nCopies). Proporciona adems varias constantes que representan colecciones de datos vacas, por ejemplo EMPTY_SET y EMPTY_LIST.

2.5. Casos especiales Esta clase proporciona mtodos que permiten obtener conjuntos

Licenciatura en Sistemas de Informacin

Prof. Cristina Greiner

Programacin IV

Tema 5

Persistencia De Objetos
Normalmente, cuando se codifica un programa, se hace con la intencin de que el programa pueda interactuar con los usuarios del mismo, es decir, que el usuario pueda pedirle que realice determinada tarea, suministrndole datos con los que debe llevar a cabo la tarea solicitada. Se espera que el programa los manipule de alguna forma, proporcionando una respuesta a lo solicitado. Por otra parte, en muchas ocasiones interesa que el programa guarde los datos que se le han introducido, de forma que al finalizar el proceso, los datos no se pierdan y puedan ser recuperados en una sesin posterior. La forma habitual de hacer esto es mediante la utilizacin de dispositivos de almacenamiento secundario o externo (normalmente un disco). Se llama persistencia a la capacidad de una entidad de trascender el tiempo o el espacio. En la programacin previa al paradigma de objetos estaba representada con la entrada y salida de datos. Es un concepto importante, pues 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. Esto es particularmente importante en la actualidad, dado que se ha vuelto cotidiano el compartir archivos entre distintas plataformas, invocar procedimientos remotos o usar objetos distribuidos. Un objeto persistente es aqul que conserva su estado en un medio de almacenamiento permanente, pudiendo ser reconstruido por el mismo u otro proceso. Al objeto no persistente lo llamamos efmero. Los datos generalmente se almacenan con algn tipo de organizacin, por ejemplo, un registro, que agrupa datos de diferentes tipos (enteros, string, etc). En los lenguajes de programacin OO, como Java, C++, etc, los datos se organizan en un tipo de datos definido por el usuario (UDT) que recibe el nombre de Clase. Esto presenta la ventaja de que adems de incluir los campos tradicionales de un registro (en forma de atributos) tambin puede incorporar una serie de mtodos que permiten procesar de manera mas fcil los campos o atributos de la clase. Sin embargo, a la hora de hacer persistente estos UDT, la tecnologa que los soporta (Bases de datos Orientadas a ObjetoBDOO o Bases de Dato Objeto Relacional-BDOR), an se encuentra en etapa de investigacin, y no tiene gran difusin a nivel comercial. Las dificultades encontradas son inconvenientes inherentes a los productos que se utilizan para la programacin, y a la propia naturaleza de los objetos, sobre todo derivados de la composicin. Otro de los problemas relacionados con la persistencia tiene que ver con la evolucin del diseo del modelo de clases. En algunas metodologas de desarrollo, como XP, esto es sumamente frecuente. El problema planteado es: qu pasa si se almacena un objeto y, cuando se lo quiere recuperar en la misma aplicacin, la clase ha cambiado de estructura? Hasta el da de hoy, los diseadores de lenguajes de programacin orientados a objetos no han encontrado un modelo de persistencia uniforme para todos los objetos. En consecuencia, muchos lenguajes han optado por no soportar la persistencia de objetos o slo lo hacen para algunas familias de clases, generalmente predefinidas. A pesar de estos contratiempos, muchas instituciones, entre ellas el OMG, estn haciendo esfuerzos por llegar a un estndar de persistencia en los lenguajes de POO.

Separacin de la capa de acceso a datos


Se puede pensar una aplicacin como la conjuncin de tres componentes o capas: Capa de acceso a datos: se encarga del acceso a bases de datos y archivos, para consulta, almacenamiento o persistencia. Capa de reglas del negocio: implementa la lgica de la aplicacin. Capa de interfaz de usuario: se encarga de presentar la informacin a los usuarios y recibir sus solicitudes. El objetivo principal de separar un sistema en capas es el de permitir cambios de implementacin en alguna de las capas sin afectar a otras. Por ejemplo, si se desarrolla un sistema cuyo motor de base de datos es uno en particular, debera poder cambiarse esta eleccin sin necesidad de modificar las clases que implementan la lgica o la interfaz del usuario.

Licenciatura en Sistemas de Informacin

Prof. Cristina Greiner

Programacin IV

Tema 5

Otra finalidad del modelo de capas es 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, sin que esto deba afectar en nada el ncleo del programa en s. Este objetivo es cada vez ms importante al avanzar la tecnologa de la informacin y generalizarse la idea de datos compartidos. Si el propsito es que todo objeto debe poder guardarse en forma permanente, el ideal en cuanto a persistencia sera que cada clase tenga un mtodo para guardar objetos y otro para recuperarlos, consistentes entre s. Adems, los lenguajes orientados a objetos deberan dar soporte directo a la persistencia y debera haber formas de almacenar objetos (cdigo+datos) en bases de datos. Sin embargo, hay una contradiccin entre este ideal y el principio de separacin de modelo y capa de acceso a datos: si toda c1ase debe saber cmo guardarse, el modelo debe conocer dicha capa. Por lo tanto, sigue la bsqueda de soluciones en este sentido.

Persistencia y bases de datos relacionales


Una base de datos es una coleccin de datos interrelacionados, almacenados sin redundancias perjudiciales en la cual los datos se almacenan de modo que resulten independientes de los programas que los usan y existen mtodos para incorporar o extraer datos. Las hay de diversos tipos: en red, jerrquicas, relacionales, etc. En el uso corporativo prcticamente la totalidad de las bases de datos son relacionales. La relacin entre bases de datos y objetos es interesante por la importancia de las bases de datos en las empresas y el avance de la tecnologa de orientacin a objetos. Por eso, no puede haber autntica POO si no se puede garantizar la persistencia en bases de datos. A lo largo del tiempo, ha habido diferentes niveles de orientacin a objetos en las bases de datos. En un primer momento, lo nico que se hizo fue incorporar BLOBs (Binary Large Object, largas cadenas de bytes sin formato alguno) en las bases de datos relacionales, de modo de poder representar cualquier tipo de informacin como contenido, as como partes variantes de los objetos. El inconveniente principal es que los BLOBs no sirven para realizar bsquedas o indexaciones. El siguiente paso fue la incorporacin de "front-ends" orientados a objetos a las bases de datos relacionales. Esta tecnologa, que es an la que ms se utiliza, se la llama tambin de bases de datos relacionales basadas en objetos (BDOR). En este caso, hay una capa filtrante que traduce entre objetos y el modelo relacional tradicional. Por lo tanto, los objetos deben ser interceptados antes de ser almacenados y traducidos de formato, y al recuperarlos se hace el procedimiento inverso. Entre sus ventajas est la simplicidad de implementacin, que aprovecha el xito del modelo relacional y de SQL y la facilidad de adaptacin de recursos humanos y de datos. Sin embargo, presenta tiempos de respuesta elevados y no hay una genuina orientacin a objetos, no habiendo herencia, polimorfismo, ni nada que se le parezca. Adems, el software de traduccin est disociado del universo del sistema: es una solucin de problemas tecnolgicos. En definitiva, esta solucin deja al descubierto la complejidad de representar un objeto complejo en el modelo relacional.

Bases de datos orientadas a objetos


Si la aplicacin que se est creando debe usar datos corporativos generados con el modelo relacional, probablemente ocurra que es ms econmico el uso de bases de datos relacionales basadas en objetos. Lo mismo puede ocurrir en algunos casos en los cuales se requiera almacenar objetos sencillos y el modelo relacional sea suficiente. Pero si alguna de estas hiptesis no se cumple, usar paradigmas distintos en el modelo de desarrollo y en el modelo de datos persistentes puede ser una fuente de problemas. De todas maneras, las bases de datos orientadas a objetos (BDOO) no surgieron por este nico motivo, sino tambin para superar las limitaciones de las bases de datos relacionales y para ofrecer funcionalidades ms avanzadas. Es que 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 para manejar multimedia. Adems, el modelo relacional identifica objetos con los valores que contienen, al punto que no

Licenciatura en Sistemas de Informacin

Prof. Cristina Greiner

Programacin IV

Tema 5

puede haber dos filas exactamente iguales en una tabla, mientras el modelo orientado a objetos puede perfectamente trabajar con dos objetos distintos cuyo estado sea el mismo. Esto est basado en una de las caractersticas intrnsecas del objeto: la identidad. Una BDOO debe proveer, como mnimo: Persistencia. Control de acceso. Consultas basadas en valores de propiedades y no en la ubicacin. 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. La herencia, el polimorfismo, el mantenimiento de versiones anteriores de los objetos y clases y otras propiedades, pueden ser deseables, pero no constituyen condiciones necesarias para que la base de datos se pueda caratular como orientada a objetos.

Los lenguajes orientados a objetos y la persistencia


La entrada y salida es un aspecto que ha ido perdiendo la simplicidad que tena en los lenguajes que se utilizaban en la dcada de los 80. La ansiedad por generalizar todo, por hacer que las operaciones de entrada y salida fueran coherentes con el resto del lenguaje, la conversin de simples instrucciones o procedimientos en mtodos de clase y la tendencia a soportar entrada y salida sobre distintos dispositivos, incluso sobre equipos remotos, ha llevado a una gran complejidad en este tema. Sin embargo, algunos lenguajes han hecho un esfuerzo por preservar la simplicidad. Por ejemplo, C++ ha introducido una sintaxis de entrada y salida considerablemente ms simple que la de C, con los operadores y y los dispositivos cin, cout y cerr, todos definidos en una biblioteca estndar. Java hizo lo propio: la simple llamada a los mtodos System.in.read y System.out.print facilitan la entrada/salida de datos. Sin embargo, el mayor problema es que no se ha logrado una persistencia adecuada en la mayora de los lenguajes, por lo que el enorme esfuerzo todava no ha dado sus frutos. En C++ hay una serie de clases de flujos (en ingls, streams) subclases de ios o de streambuf, con una serie de mtodos para la entrada y salida. En Java existe una clase File y sus subclases, que permiten manejar estructuras de directorios, y una serie de jerarquas derivadas de las clases InputStream, OutputStream, Reader y Writer, que permiten un completo manejo de flujos de entrada y salida. En el campo de las bases de datos, los lenguajes orientados a objetos no han avanzado nada, no slo porque no han implementado bases de datos orientadas a objetos, sino que incluso dejan a cargo del programador la construccin de las interfaces o capas que convierten estructuras de objetos en bases de datos relacionales. Lo que s han implementado en muchos casos, es una suerte de SQL multiplataforma que, con bastante trabajo, se puede hacer que funcione para los distintos modelos de bases de datos relacionales. Tal cosa ocurre en Delphi, en C++ y en Java con JDBC. Mientras se contina investigando, el OMG ha desarrollado algunas especificaciones y varias empresas han desarrollado productos ad hoc para varios lenguajes de programacin orientados a objetos. En la mayora de los casos se trata de filtros que mapean la informacin desde una aplicacin orientada a objetos a un almacenamiento de datos no orientado a objetos.

Clases para entrada/salida en Java


Java proporciona una extensa jerarqua de clases, agrupadas en el paquete estndar de la API de Java, denominado java.io que incorpora interfaces, clases y excepciones, para acceder a distintos tipos de archivos. Estas clases predefinidas cuentan con todos los mtodos necesarios para leer, grabar y manipular los datos.

Licenciatura en Sistemas de Informacin

Prof. Cristina Greiner

Programacin IV

Tema 5

La manera de representar las entradas y salidas en Java es a base de streams (flujos de datos). Un stream es una conexin entre el programa y la fuente o destino de los datos. La informacin se traslada en serie (un carcter a continuacin de otro) a travs de esta conexin. Esto da lugar a una forma general de representar muchos tipos de comunicaciones. Por ejemplo, cuando se quiere imprimir algo en pantalla, se hace a travs de un stream que conecta el monitor al programa. Se da a ese stream la orden de escribir algo y ste lo traslada a la pantalla. Existen dos tipos de Entrada/Salida:

1. Entrada/Salida estndar: teclado y pantalla


El acceso a la entrada y salida estndar es controlado por tres objetos que se crean automticamente al iniciar la aplicacin: System.in, System.out y System.err
System.in

Este objeto implementa la entrada estndar (normalmente teclado). Los mtodos que proporciona son:

System.out

read(): Devuelve el carcter que se ha introducido por el teclado leyndolo del buffer de entrada y lo elimina del buffer para que en la siguiente lectura sea ledo el siguiente carcter. Si no se ha introducido ningn carcter por el teclado devuelve el valor -1. skip(n): Ignora los n caracteres siguientes de la entrada.

Este objeto implementa la salida estndar. Los mtodos que proporciona son:

print(a): Imprime a en la salida, donde a puede ser cualquier tipo bsico Java ya que Java hace su conversin automtica a cadena. println(a): Es idntico a print(a) salvo que con println() se imprime un salto de lnea al final de la impresin de a.

System.err

Este objeto implementa la salida en caso de error. Normalmente esta salida es la pantalla o la ventana de la terminal como con System.out, pero puede ser interesante redirigirlo, por ejemplo hacia un fichero, para diferenciar claramente ambos tipos de salidas. Las funciones que ofrece este objeto son idnticas a las proporcionadas por System.out. 2. Entrada/Salida a travs de archivos: se trabaja con archivos de disco.

Tipos de ficheros
En Java es posible utilizar dos tipos de ficheros (de texto o binarios) y dos tipos de acceso a los ficheros (secuencial o aleatorio). Los ficheros de texto estn compuestos de caracteres legibles, mientras que los binarios pueden almacenar cualquier tipo de datos (int, float, boolean,...). Una lectura secuencial implica tener que acceder a un elemento antes de acceder al siguiente, es decir, de una manera lineal (sin saltos). Sin embargo los ficheros de acceso aleatorio permiten acceder a sus datos de una forma aleatoria, es decir, indicando una determinada posicin desde la que leer/escribir.

Jerarqua de Clases
En el paquete java.io existen varias clases de las cuales se puede crear instancias para tratar todo tipo de archivos. Existen dos familias de jerarquas distintas para la entrada/salida de datos. La diferencia principal consiste en que una opera con bytes y la otra con caracteres (el carcter de Java est formado por dos bytes porque sigue el cdigo Unicode). En general, para el mismo fin hay dos clases que manejan bytes (una clase de entrada y otra de salida) y otras dos que manejan caracteres. Desde Java 1.0, la entrada y salida de datos del programa se poda hacer con clases derivadas de InputStream (para lectura) y OutputStream (para escritura). Estas clases tienen los mtodos bsicos read() y write() que manejan bytes y que no se suelen utilizar directamente. Las jerarquas de clases son las siguientes:

Licenciatura en Sistemas de Informacin

10

Prof. Cristina Greiner

Programacin IV

Tema 5

En Java 1.1 aparecieron dos nuevas familias de clases, derivadas de Reader y Writer, que manejan caracteres en vez de bytes. Estas clases resultan ms prcticas para las aplicaciones en las que se maneja texto. Las jerarquas son las siguientes:

Algunas clases definen de dnde, o a dnde, se envan los datos, es decir, el dispositivo con que conecta el stream. Otras aaden caractersticas particulares a la forma de enviarlos. La intencin es que se combinen para obtener el comportamiento deseado. Por ejemplo:
BufferedReader entrada = new BufferedReader(new FileReader("Alumnos.txt"));

Con esta lnea se ha creado un stream (entrada) que permite leer del archivo Alumnos.txt. Adems, se ha creado a partir de l un objeto BufferedReader (que aporta la caracterstica de utilizar buffer). Los caracteres que lleguen a travs del FileReader pasarn a travs del BufferedReader, es decir utilizarn el buffer. Esto puede tambin utilizarse para leer caracteres desde el teclado, pasndole un objeto de tipo System.in, que hace referencia a la entrada estndar.
BufferedReader tecla = new BufferedReader(new InputStreamReader(System.in));

De la amplia jerarqua de clases, las tres principales son: FileOutputStream: Para escritura de archivos de texto a los que se accede de forma secuencial. FileInputStream: Para lectura de archivos de texto a los que se accede de forma secuencial. RandomAccessFile: Archivo entrada o salida binario con acceso aleatorio. Es la base para crear los objetos de tipo archivo acceso aleatorio. Estos archivos permiten multitud de operaciones: saltar hacia delante y hacia atrs para leer la informacin necesaria, e incluso leer o escribir partes del archivo sin necesidad de cerrarlo y volverlo a abrir en un modo distinto.

Licenciatura en Sistemas de Informacin

11

Prof. Cristina Greiner

Programacin IV
Generalidades
Para trabajar con un archivo siempre se debe actuar de la misma manera:

Tema 5

1. Se abre el fichero.
Para ello hay que crear un objeto de la clase correspondiente al tipo de fichero a manejar, y el tipo de acceso a utilizar: TipoDeFichero obj = new TipoDeFichero( ruta ); Donde ruta es la ruta de disco en que se encuentra el archivo o un descriptor de archivo vlido. Este formato es vlido, excepto para los objetos de la clase RandomAccessFile (acceso aleatorio), para los que se debe instanciar de la siguiente forma: RandomAccessFile obj = new RandomAccessFile( ruta, modo ); Donde modo es una cadena de texto que indica el modo en que se desea abrir el fichero: "r" para slo lectura o "rw" para lectura y escritura.

2. Se utiliza el fichero.
Para ello cada clase presenta diferentes mtodos de acceso para escribir o leer en el fichero. La Clase RandomAccessFile presenta, adems de los clsicos mtodos de lectura/escritura, otro grupo de mtodos que trabajan con un ndice que proporciona esta clase, y que indica en qu posicin del archivo se encuentra el puntero. Con l se puede trabajar para posicionarse en el archivo.

Mtodos de desplazamiento
Cuenta con una serie de funciones para realizar el desplazamiento del puntero del fichero. Se debe tener en cuenta que cualquier lectura o escritura de datos se realizar a partir de la posicin actual del puntero del fichero. long getFilePointer():Devuelve la posicin actual del puntero del fichero. void seek( long l ): Coloca el puntero del fichero en la posicin indicada por l. Un fichero siempre empieza en la posicin 0. int skipBytes( int n ): Intenta saltar n bytes desde la posicin actual. long length(): Devuelve la longitud del fichero.

3. Gestin de excepciones
Se puede observar que todos los mtodos que utilicen clases de este paquete deben tener en su definicin una clusula throws IOException. Los mtodos de estas clases pueden lanzar excepciones de esta clase (o sus hijas) en el transcurso de su ejecucin, y dichas excepciones deben de ser capturadas y debidamente gestionadas para evitar problemas.

4. Se cierra el fichero y se destruye el objeto.


Para cerrar un fichero lo que hay que hacer es destruir el objeto. Esto se puede realizar de dos formas: dejando que sea el recolector de basura de Java el que lo destruya cuando no lo necesite (no se recomienda) o destruyendo el objeto explcitamente mediante el uso del procedimiento close() del objeto: obj.close()

Licenciatura en Sistemas de Informacin

12

Prof. Cristina Greiner

Programacin IV

Tema 5

Clases para el tratamiento de Fechas en java


En las primeras versiones de java el manejo de fechas pasaba exclusivamente por el uso de la clase java.util.Date, pero a partir de la versin JDK 1.1 fueron aadidas nuevas funcionalidades en otras clases de apoyo como Calendar, TimeZone, Locale y DateFormat y descargando de funcionalidad a la clase Date, si bien, sigue siendo la clase base para el uso de fechas. Existen tres clases en la documentacin Java API que tienen que ver con las fechas Date crea un objeto Date (paquete java.util) Calendar configura o cambia la fecha de un objeto Date (paquete java.util). DateFormat muestra la fecha en diferentes formatos (paquete java.text). La jerarqua de clases es la siguiente:
java.util java.lang.Object java.util.Date java.util java.lang.Object java.util.Calendar java.util.GregorianCalendar java.text java.lang.Object java.text.Format java.text.DateFormat java.text.SimpleDateFormat

Se deben importar los paquetes correspondientes. import java.util.*; import java.text.*; La clase Date representa un momento especfico del tiempo en milisegundos, mientras que Calendar permite obtener nmeros enteros que especifican el da, mes, ao, hora, etc. de dicha fecha. Es decir, lo que eran los antiguos mtodos de .getDay(), .getMonth(), etc.

Trabajando con fechas


Clase Calendar
Para mostrar fecha y hora proceder de la siguiente manera: 1. Obtener una instancia de la clase Calendar mediante el mtodo .getInstance(). Esto devuelve un calendario con los valores por defecto establecidos en el sistema en cuanto a hora y formato. 2. Obtener los valores de inters mediante el mtodo get(). Dicho mtodo admite como parmetros una serie de constantes definidas en la clase Calendar que representan el da, mes, ao, etc. Estas constantes son Calendar.DATE, Calendar.MONTH, Calendar.YEAR, etc. 3. Otras constantes permiten saber si la fecha es un da u otro, un mes u otro. Estas constantes son Calendar.FRIDAY, Calendar.MONDAY, etc. para los das, Calendar.JUNE, Calendar.NOVEMBER, etc. para los meses.

Licenciatura en Sistemas de Informacin

13

Prof. Cristina Greiner

Programacin IV
Ejemplo:
java.util.Calendar fecha = java.util.Calendar.getInstance(); System.out.println(fecha.get(java.util.Calendar.DATE) + "/" + fecha.get(java.util.Calendar.MONTH) + "/" + fecha.get(java.util.Calendar.YEAR));

Tema 5

Muestra con este formato Clase Date

2/8/2006

Para mostrar fecha y hora proceder de la siguiente manera: 1. Obtener una instancia de la clase Date mediante el mtodo Date(). Devuelve una fecha con los valores por defecto establecidos en el sistema. 2. Existen varios mtodos para esta clase, sin embargo la mayora es deprecated, dado que a partir de las nuevas versiones de java se trabaja preferentemente con la clase Calendar Ejemplo:
Date hoy = new Date(); System.out.println(hoy);

Muestra con este formato

Sat Sep 02 07:40:43 ART 2006

Formato de fechas
Clase DateFormat
Mediante la clase Calendar, nicamente se pueden mostrar los valores enteros del da, mes y ao. Para mostrar las fechas en otro formato como 18-Nov-2002, 18 de noviembre de 2002, etc., se debe usar un formateador de fechas mediante la clase DateFormat. Los pasos a seguir son: 1. Obtener una instancia del calendario 2. Obtener la fecha actual del calendario 3. Instanciar el formateador
DateFormat formato = DateFormat.getDateInstance(DateFormat.FULL); Calendar calendario = Calendar.getInstance(); Date fecha = calendario.getTime();

Este mtodo permite pasarle un estilo de formato. Dentro de los estilos estn: SHORT, totalmente numrico (18/11/05 O 9:01) MEDIUM, formato largo (18-nov-05 O 9:00:20) LONG, otro formato largo (18 de noviembre de 2005 O 9:02:12 GMT+01:00) FULL, con la especificacin completa (lunes 18 de noviembre de 2005 O 09H03' GMT+01:00)

Clase SimpleDateFormat
import java.text.SimpleDateFormat; import java.util.Date; public class Fecha{ public static void main(String cvr[]){ Date fecha=new Date(); SimpleDateFormat sdf=new SimpleDateFormat("dd/MM/yyyy"); System.out.println("La fecha de hoy es:" + sdf.format(fecha)); } }

Licenciatura en Sistemas de Informacin

14

Prof. Cristina Greiner

Programacin IV
El formato puede ser: dd.MM.yy 09.04.98 yyyy.MM.dd G 'at' hh:mm:ss z 1998.04.09 AD at 06:15:55 PDT EEE, MMM d, ''yy Thu, Apr 9, '98 h:mm a 6:15 PM H:mm 18:15 H:mm:ss:SSS 18:15:55:624 K:mm a,z 6:15 PM,PDT yyyy.MMMMM.dd GGG hh:mm aaa

Tema 5

Operando con fechas


La clase GregorianCalendar cuenta con mtodos para operar con fechas en Java. 1) Sumar/restar das a una fecha
a. Crear calendario con la fecha actual GregorianCalendar calendario = new GregorianCalendar();

b. Restar la cantidad en la unidad conveniente (semanas,meses,aos...)


calendario.add(Calendar.DATE, -numero_dias);

Con Calendar se puede obtener el Date correspondiente y a partir de ah formatear la fecha al patrn deseado con DateFormat o SimpleDateFormat 2) Mtodos de comparacin
public boolean after(Object fecha)

Calendar Retorna true si la fecha a la que se aplica el mtodo es posterior a la del parmetro.
fecha: de tipo public boolean before(Object fecha)

Calendar Retorna true si la fecha a la que se aplica el mtodo es anterior a la del parmetro.
fecha: de tipo public boolean equals(Object fecha)

Calendar Retorna true si la fecha a la que se aplica el mtodo es igual a la del parmetro.
fecha: de tipo

Licenciatura en Sistemas de Informacin

15

Prof. Cristina Greiner