Documente Academic
Documente Profesional
Documente Cultură
Unidad2
Introduccinalossistemasdeinformacin
9/23/2009
Contenido
UNIDAD 2 ................................................................................................................................. 3 Introduccin a programacin orientada a objetos .................................................................. 3 Breve revisin histrica ..................................................................................................... 3 Evolucin de los lenguajes de programacin..................................................................... 3 Evolucin en cuanto a la conceptualizacin ...................................................................... 5 Programacin Orientada al Objeto..................................................................................... 7 Evolucin en cuanto al enfoque ......................................................................................... 7 Breve historia de la OOP ................................................................................................. 10 Programacin Orientada al Objeto................................................................................... 11 Simulacin del Pescado: Un Programa OO que Simula la Vida Acutica ...................... 17 Desarrollando Programas en Java ........................................................................................ 22 Definicin de servlet ........................................................................................................ 22 Compilando el cdigo fuente. .......................................................................................... 23 Formas HTML para hacer llamadas a Servlets ................................................................ 26 Ejecutando un Servlet Java .............................................................................................. 27 Trabajando con Java ............................................................................................................ 30 Clase CatFish ................................................................................................................... 30 Definiendo Clases. .......................................................................................................... 32 Atributos de la clase. ........................................................................................................ 33 Comportamiento de las clases .......................................................................................... 33 Trabajando con la sentencia if ......................................................................................... 35 Elementos de los Servlets .................................................................................................... 37 Analizando en profundidad .............................................................................................. 38 Recibiendo Entrada del Usuario ...................................................................................... 43 Depurando (debugging) un Servlet .................................................................................. 46 Planeacin del desarrollo de un Servlet ........................................................................... 48 Planeando la Solucin ...................................................................................................... 52 Buenas practicas de desarrollo en Java ................................................................................ 63 El proceso de la programacin ......................................................................................... 63 Documentacin de API de Java ....................................................................................... 64 Gua de Estilo de codificacin ......................................................................................... 66 Comentando el Cdigo Fuente......................................................................................... 67 Javadoc.......................................................................................................................... 67 Gua de estilo sencilla ...................................................................................................... 67 Aspectos Fundamentales de Programacin Orientada a Objetos ........................................ 71 Diseo de Clases .............................................................................................................. 71 Estado de un Objeto e Interfase del Objeto .............................................................. 73 Ejemplo de un Proceso de Diseo: Cajero de un Banco (Bank Teller) ........................... 76 Ejemplo de un Proceso de Diseo: AccountsLedger .............................................. 79 2
UNIDAD 2
secuencialmente, es decir, una detrs de otra. Por tanto, como la forma de programarlos es introduciendo secuencias de ceros y unos (lo que llamamos bits); puede imaginarse la gran probabilidad que existe de error al introducir sucesiones enormemente largas; adems, una vez cometido un error, intentar encontrarlo y corregirlo puede llevarnos antes al manicomio con un grave cuadro de psicosis, que a la solucin del problema. De hecho, desde hace ya muchos aos, los microprocesadores, que, como probablemente sabr, son la maquinaria ejecutora de los ordenadores, se fabrican para ser programados, no en binario (secuencia de unos y ceros), sino en hexadecimal (un nmero hexadecimal equivale a 16 ceros o unos). Cronolgicamente el primer avance importante vino con la aparicin de los lenguajes ensambladores. A estos lenguajes los llamamos de "bajo nivel", ya que se hallan estrechamente ligados a la forma de trabajo de la mquina con la que programamos y se opera con ellos de modo muy similar a como se hace cuando trabajamos en hexadecimal. Quizs usted pueda pensar que no hay gran diferencia entre programar en hexadecimal (o en binario), y hacerlo a travs de un ensamblador, y es cierto, pero este logro no lo es tanto en cuanto al modo de trabajo (que segua siendo precario y tedioso) como en cuanto a la nueva concepcin que ello implica: por primera vez aquello que nosotros escribimos no es entendible directamente por la mquina, sino que debe ser previamente traducido para que la mquina lo entienda. Un lenguaje ensamblador lo nico que hace es transcribir unos nemnicos (palabras fciles de recordar) a la secuencia ceros y unos a los que el nemnico representa y que s son entendibles por la mquina. Por ejemplo, supongamos que deseamos almacenar un nmero en uno de los registros del microprocesador (un caso frecuente cuando se programa a bajo nivel). Supongamos que el nmero, para simplificar las cosas es el 4 (tiene la misma notacin en decimal que en hexadecimal) y el registro el AX (uno de los registros de la familia de microprocesadores 80de la marca Intel), la instruccin tendra un aspecto algo as:
queden ganas de ponerse a re-escribirlo para otra mquina distinta. Con lo que la portabilidad queda mermada considerablemente. Hecho que no debe ocurrir con un lenguaje de alto nivel. A estas alturas, es posible que usted est pensado que todo esto es demasiado bonito para ser cierto y que en algn lugar debe estar el problema. Efectivamente, no nos llevemos a engao, todo esto al final, se queda en papel mojado y buenas intenciones, debe ser que al dios de la computacin le agrada hacernos la vida complicada. La cuestin tiene dos vertientes bien distintas: por un lado, los programas realizados con lenguajes de alto nivel, realizan los mismo procesos de un modo ms lento que de haberlos escrito con uno de bajo nivel, este problema no es demasiado gravoso si echamos un vistazo a la evolucin en la potencia de clculo de las mquinas en los ltimos diez aos. Salvo para programas muy especficos, o de gran rendimiento, no habra ningn problema, en escribir nuestras aplicaciones en un lenguaje de alto o bajo nivel. Donde est el problema entonces? se preguntar usted. La respuesta es que est en la portabilidad. En teora, y solo en teora, puesto que un lenguaje de alto nivel es independiente de la mquina donde se ejecute, el mismo cdigo que escribimos para una mquina puede ser traducido al lenguaje hexadecimal en esa mquina o en otra cualquiera que disponga de traductor para ese lenguaje. Por ejemplo, si yo escribo un programa en lenguaje BASIC para una computadora, este mismo programa podra ejecutarse en cualquier otra mquina que dispusiese de traductor de BASIC para ella. Pero aqu aparece la torre de Babel de la informtica. Existen traductores de lenguaje BASIC para multitud de mquinas diferentes, el problema reside en que cada mquina tiene un dialecto del lenguaje BASIC distinto a los dems, con lo que la portabilidad se hace imposible. Y por qu ocurre esto? Eso ya son cuestiones de marketting, poltica de empresas y sociedad de consumo y libre mercado, algo que tiene muy poco que ver con los investigadores y las buenas intenciones.
continuamente de unos trozos de cdigo a otros. Veamos un ejemplo tpico de cmo se abordara una misma tarea desde las dos perspectivas. La tarea consiste en mostrar los nmeros del 1 a 10. Lo explicaremos en pseudocdigo (exponer los pasos a realizar en lenguaje natural, en lugar de hacerlo en alguno de los lenguajes de programacin existentes) para que resulte ms comprensible:
Programacin lineal Cada lnea de programa debe ir precedida de un identificador (una etiqueta) para poder referenciarla, para este ejemplo hemos utilizado nmeros, aunque podra utilizarse cualquier otro identificador:
1. 2. 3. 4. Hacer una variable igual a 0 Sumar 1 a esa variable Mostrar la variable Si la variable es 100 -> terminar, Si_no -> saltar a 1:
Programacin estructurada
1. Hacer una variable igual a 0 2. Mientras que sea menor que 100 -> sumar 1 y mostrarla
Lo importante aqu, es que cuando escribimos un programa usando las tcnicas de programacin estructurada, los saltos estn altamente desaconsejados, por no decir prohibidos; en cambio en BASIC, por ejemplo, son muy frecuentes (todos conocemos el prolfico GOTO <nLnea>), lo que no es nada conveniente si queremos entender algo que escribimos hace tres meses de forma rpida y clara. De hecho, cuando el traductor (ya sea intrprete o compilador) cambia nuestro programa a cdigo mquina, lo convierte a estilo lineal, pero eso es asunto de la mquina, nosotros escribimos y corregimos nuestro programa de un modo claro, y podemos seguir el flujo de la informacin con facilidad. Lo que se intenta, es que el programador pueda hacer programas cada vez ms extensos sin perderse en un entramado de lneas de cdigo interdependientes. Un programa en estilo lineal se parece a la red neuronal del cerebro, si usted ha visto alguna vez una foto de estas, no lo habr olvidado: en esa maraa de neuronas y conexiones nerviosas no hay quien se entienda, y si no que se lo pregunten a los neurofisilogos. Para evitar esto, junto con la programacin estructurada aparece un concepto que nos permite abarcar programas ms amplios con menor esfuerzo: el de funcin. La idea es muy simple: muchas veces realizo procesos que se repiten y en los que slo cambia algn factor, si trato ese proceso como un subprograma al que llamo cada vez que lo necesito, y cada vez que lo llamo puedo cambiar ese factor, estar reduciendo el margen de error, al reducir el nmero de lneas que necesito en mi programa, ya que no tengo que repetir todas esas lneas cada vez que quiera realizar el proceso, con una sola lnea de llamada al subprograma ser suficiente; adems, de haber algn fallo en este proceso el error queda circunscrito al trozo de cdigo de la funcin. As, las funciones podemos entenderlas como unas cajas negras, que reciben y devuelven valores. Solo tengo que programarlas una vez, las puedo probar por separado y comprobar que funcionan correctamente, una vez terminadas puedo olvidarme de cmo las hice y usarlas siempre que quiera. Simultneamente al concepto de funcin aparece el de variables de mbito reducido. Todos recordaremos nuestros nefastos das del BASIC, en los que cualquier variable usada en el programa, era conocida en todo el programa. Resultado: cuando habamos definido
500 variables, no nos acordbamos para qu serva cada una ni que nombres habamos usado y cuales no. Con un lenguaje estructurado, las variables son conocidas solo por aquellas partes del programa donde nos interesa que lo sean; pudiendo re-usar los nombres de las variables sin que haya colisin, siempre que estas se utilicen en mbitos distintos.
Programacin Procedural
Casi todos los lenguajes que conocemos trabajan de forma procedural. Java, C, Pascal , BASIC, Cobol, Fortran, APL, RPG, Clipper, etc. En ellos, debemos establecer, hechos (datos), reglas para el manejo de esos datos y de decisin y tenemos que decirle al lenguaje cmo alcanzar el objetivo que se persigue. Es decir, donde buscar la informacin, cmo manipularla, cuando parar, etc. Si usted es programador de algn lenguaje procedural, todo esto le parecer obvio, pero no funciona as con los lenguajes declarativos.
Programacin Declarativa
Los lenguajes ms conocidos que existen hasta ahora, salvo PROLOG, son todos procedurales, ste es declarativo. ProLog es acrnimo de PROgramming in LOGic. Este lenguaje fue desarrollado en la universidad de Marsella hacia 1970 por Alan Clomerauer y sus colegas. ProLog, se basa en manipulaciones lgicas, utiliza la lgica proposicional -lgica de predicados- para realizar sus deducciones. En ProLog no programamos, sino que declaramos hechos, es la maquinaria del lenguaje quien se encargar de extraer las conclusiones que resulten inferibles de estos hechos. A esta maquinaria se le llama motor de inferencias, que es, por otro lado, el corazn de un Sistema Experto. Probablemente de este tipo de programas -los ms famosos de la Inteligencia Artificial -, habr usted odo hablar.
Es cierto sin embrago, que para poder aplicar OOP al 100%, es necesario que el lenguaje nos proporcione una serie de mecanismos inherentes al propio lenguaje. En cualquier caso, la OOP es casi 100% procedural y, desde luego, no es en absoluto declarativa. El problema, es el mismo que aparece a la hora de dilucidar donde acaba un color y comienza otro en el arco iris. Siempre que hacemos una clasificacin de la realidad, nos encontramos con elementos que son fronterizos entre una clase y otra y son de difcil ubicacin. Sin embargo, no queda ms remedio, a efectos didcticos que realizarlas. Nos sentimos ms inclinados limitar los enfoques en programacin a los dos primeros, dejando fuera a la OOP. Posiblemente, y con el tiempo, reconsideremos esta postura y estemos de acuerdo con estos y otros autores; al fin y al cabo, la OOP an no est completamente asentada, y no sabemos donde nos habr llevado en los prximos aos.
Qu es la OOP? Comenzaremos dando una definicin por exclusin de lo que es la OOP, es decir, vamos a decir primero qu no es la OOP, para, luego, intentar dar una definicin de 8
Como puede ver, esto supone realmente una nueva concepcin en el desarrollo de programas, algo radicalmente nuevo y de una potencia y versatilidad hasta ahora inimaginables. Si usted es programador de la "vieja escuela" le parecer increble, sin embargo, y como podr comprobar, es totalmente cierto.
10
conseguido darle una gran potencia y flexibilidad al ms famoso lenguaje, el C. Llegados a este punto se hace necesario aclarar que los lenguajes de OPP, podemos clasificarlos en puros e hbridos. Diremos que un lenguaje es OOP puro, cuando se ajusta completamente a los principios que esta tcnica propone y contempla la posibilidad de trabajar exclusivamente con clases. Diremos que un lenguaje es hbrido de OOP y algn otro, cuando ese lenguaje, que normalmente exista antes de la aparicin de la OOP, incorpora en mayor o menor medida facilidades para trabajar con clases. De este modo, C++ es un lenguaje OOP hbrido. De hecho, C++ no incorpora todas las caractersticas de un lenguaje OOP, y no lo hace principalmente, porque es un lenguaje compilado y ello impide que se resuelvan ciertas referencias en tiempo de compilacin necesarias para dotar a las clases de algunas de sus cualidades puramente OOP (a menos que se le dote de un motor OOP interno, el cual tiene en parte, pero esto es harina de otro costal y no forma parte de la finalidad de este libro). Hoy en da, casi todos los lenguajes ms usados en los 80 se han reconvertido en mayor o menor medida a la OOP, y han aparecido otros nuevos. Java es la estrella de los ltimos aos: es pura OOP, impecablemente concebido e implementado por Sun.
Conceptos bsicos
En este apartado veremos cuales son los principales conceptos relacionados con la OOP. Estudiaremos los conceptos de Clase, Objeto, Herencia, Encapsulacin y Polimorfismo. Estas son las ideas ms bsicas que todo aquel que trabaja en OOP debe comprender y manejar constantemente; es por lo tanto de suma importancia que los entienda claramente. De todos modos, no se preocupe si al finalizar el presente captulo, no tiene una idea clara de todos o algunos de ellos: con el tiempo los ir asentando y se ira familiarizando con ellos, especialmente cuando comience a trabajar creando sus propias clases y jerarquas de clases. Definicin de Clase Una clase, es simplemente una abstraccin que hacemos de nuestra experiencia sensible. El ser humano tiende a agrupar seres o cosas -objetos- con caractersticas similares en
11
grupos -clases-. As, aun cuando existen por ejemplo multitud de vasos diferentes, podemos reconocer un vaso en cuanto lo vemos, incluso aun cuando ese modelo concreto de vaso no lo hayamos visto nunca. El concepto de vaso es una abstraccin de nuestra experiencia sensible. Quizs el ejemplo ms claro para exponer esto lo tengamos en las taxonomas; los bilogos han dividido a todo ser (vivo o inerte) sobre la tierra en distintas clases. Tomemos como ejemplo una pequea porcin del inmenso rbol taxonmico: Ellos, llaman a cada una de estas parcelas reino, tipo, clase, especie, orden, familia, gnero, etc.; sin embargo, nosotros a todas las llamaremos del mismo modo: clase. As, hablaremos de la clase animal, clase vegetal y clase mineral, o de la clase flidos y de las clases leo (len) y tigris (tigre). Cada clase posee unas cualidades que la diferencian de las otras. As, por ejemplo, los vegetales se diferencian de los minerales -entre otras muchas cosas- en que los primeros son seres vivos y los minerales no. De los animales se diferencian en que las plantas son capaces de sintetizar clorofila a partir de la luz solar y los animales no. Como vemos, el ser humano tiende, de un modo natural a clasificar los objetos del mundo que le rodean en clases; son definiciones estructuralistas de la naturaleza al estilo de la escuela francesa de Saussure. Prosigamos con nuestro ejemplo taxonmico y bajemos un poco en este rbol de clases. Situmonos en la clase felinos (felis), aqu tenemos varias subclases (gneros en palabras de los bilogos): len, tigre, pantera, gato, etc. cada una de estas subclases, tienen caractersticas comunes (por ello los identificamos a todos ellos como felinos) y caractersticas diferenciadoras (por ello distinguimos a un len de una pantera), sin embargo, ni el len ni la pantera en abstracto existen, existen leones y panteras particulares, pero hemos realizado una abstraccin de esos rasgos comunes a todos los elementos de una clase, para llegar al concepto de len, o de pantera, o de felino. La clase len se diferencia de la clase pantera en el color de la piel, y comparte ciertos atributos con el resto de los felinos -uas retrctiles por ejemplo- que lo diferencian del resto de los animales. Pero la clase len, tambin hereda de las clases superiores ciertas cualidades: columna vertebral (de la clase vertebrados) y es alimentado en su infancia por leche materna (de la clase mamferos). Vemos cmo las clases superiores son ms generales que las inferiores y cmo, al ir bajando por este rbol, vamos definiendo cada vez ms (dotando de ms cualidades) a las nuevas clases. Hay cualidades que ciertas clases comparten con otras, pero no son exactamente iguales en las dos clases. Por ejemplo, la clase hombre, tambin deriva de la clase vertebrado, por lo que ambos poseen columna vertebral, sin embrago, mientras que en la clase hombre se halla en posicin vertical, en la clase len la columna vertebral est en posicin horizontal. En OOP existe otro concepto muy importante asociado al de clase, el de "clase abstracta". Una clase abstracta es aquella que construimos para derivar de ella otras clases, pero de la que no se puede instanciar. Por ejemplo, la clase mamfero, no existe como tal en la naturaleza, no existe ningn ser que sea tan solo mamfero (no hay ninguna instanciacin directa de esa clase), existen humanos, gatos, conejos, etc. Todos ellos son mamferos, pero no existe un animal que sea solo mamfero. Del mismo modo, la clase que se halla al inicio de la jerarqua de clases, normalmente es creada slo para que contenga aquellos datos y mtodos comunes a todas las clases que
12
de ella derivan: Son clases abstractas. En rboles complejos de jerarquas de clases, suele haber ms de una clase abstracta. Este es un concepto muy importante: el de "clase abstracta". Como hemos dicho, una clase abstracta es aquella que construimos para derivar de ella otras clases, pero de la que no se puede instanciar. Por ejemplo, la clase mamfero, no existe como tal en la naturaleza, no existe ningn ser que sea tan solo mamfero (no hay ninguna instanciacin directa de esa clase), existen humanos, gatos, conejos, etc. Todos ellos son mamferos, pero no existe un animal que sea solo mamfero. Por ltimo, adelantemos algo sobre el concepto de objeto. El len, como hemos apuntado antes, no existe, igual que no existe el hombre; existen leones en los circos, en los zoolgicos y, segn tenemos entendido, an queda alguno en la sabana africana. Tambin existen hombres (hombre en un sentido neutro, ya sea de la subclase mujer o varn), o cada uno de los que nos encontramos a diario en todas partes. Todos estos hombres comparten las caractersticas de la clase hombre, pero son diferentes entre s, en estatura, pigmentacin de la piel, color de ojos, complexin, etc. A cada uno de los hombres particulares los llamamos "objetos de la clase hombre". Decimos que son objetos de tipo hombre o que pertenecen a la clase hombre. Ms tcnicamente, Jos Luis Aranguren o Leonardo da Vinci son instanciaciones de la clase hombre; instanciar un objeto de una clase es crear un nuevo elemento de esa clase, cada nio que nace es una nueva instanciacin a la clase hombre.
Definicin de Objeto
Segn el Diccionario del Uso del Espaol de Mara Moliner (Ed. Gredos, 1983), en la tercera acepcin del termino objeto podemos leer: "Con respecto a una accin, una operacin mental, un sentimiento, etc., cosa de cualquier clase, material o espiritual, corprea o incorprea, real o imaginaria, abstracta o concreta, a la cual se dirigen o sobre la que se ejercen." No se asuste, nuestra definicin de objeto, como podr comprobar es mucho ms fcil. En OOP, un objeto es un conjunto de datos y mtodos; como imaginamos que se habr quedado igual, le vamos a dar ms pistas. Los datos son lo que antes hemos llamado caractersticas o atributos, los mtodos son los comportamientos que pueden realizar. Lo importante de un sistema OOP es que ambos, datos y mtodos estn tan intrnsecamente ligados, que forman una misma unidad conceptual y operacional. En OOP, no se pueden desligar los datos de los mtodos de un objeto. As es como ocurre en el mundo real. Vamos ahora a dar una serie de ejemplos en los que nos iremos acercando paulatinamente a los objetos informticos. Los ltimos ejemplos son para aquellos que ya conocen Java y/o C; sin embargo, estos ejemplos que exigen conocimientos informticos, no son imprescindibles para entender plenamente el concepto de clase y el de objeto. Observe que aunque los datos y los mtodos se han enumerado verticalmente, no existe ninguna correspondencia entre un dato y el mtodo que aparece a su derecha, es una simple enunciacin.
13
Ejemplo 1 Tomemos la clase len de la que hablamos antes y veamos cuales seran algunos de sus datos y de sus mtodos.
Len Color Tamao Peso Uas Retractile Colmillos Cuadrpedo Desplazarse Masticar Digerir Respirar Secretar Hormonas Parpadear Ejemplo 2
Nuestros objetos (los informticos), como hemos comentado antes, se parecen mucho a los del mundo real, al igual que estos, poseen propiedades (datos) y comportamientos (mtodos). Cojamos para nuestro ejemplo un cassette. Veamos cmo lo definiramos al estilo de OOP.
Cassette Peso Dimensiones Color Potencia Rebobinar la cinta Avanzar la cinta Grabar Reproducir Ejemplo 3
Pongamos otro ejemplo algo ms prximo a los objetos que se suelen tratar en informtica: un recuadro en la pantalla. El recuadro pertenecera a una clase a la llamaremos marco. Veamos sus datos y sus mtodos.
14
Marco Coordenada superior izquierda Coordenada inferior derecha Tipo de lnea Color de relleno Mostrarse Ocultarse Cambiar de posicin
Ejemplo 4
Vayamos con otro ejemplo ms. Este es para aquellos que ya tienen conocimientos de informtica, y en especial de lenguaje C o Java. Una clase es un nuevo tipo de dato y un objeto cada una de las asignaciones que hacemos a ese tipo de dato. int nEdad = 30; Hemos creado un objeto que se llama nEdad y pertenece a la clase integer (entero). Para crear un objeto de la clase marco lo haramos de forma muy parecida: llamando a la funcin creadora de la clase marco: Marco oCajaMsg := new Marco(); No se preocupe si esto no lo ve claro ahora, esto es algo que veremos con detenimiento ms adelante. Para crear un objeto de tipo Marco, previamente hemos tenido que crear este nuevo tipo de dato. Aun cuando ni en Java ni en C un integer sea internamente un objeto, bien podra serlo; de hecho no hay ninguna diferencia conceptual entre la clase integer y la clase Marco. La primera es una de las clases que vienen con el lenguaje y la segunda la creamos nosotros. Pero del mismo modo a como nEdad es una instancia de la clase integer, oCajaMsg es una instancia de la clase Marco (De hecho, en Java existe la clase Integer, que si es una clase "de verdad" (tanto a nivel externo como interno) y de la que se instancias objetos de tipo integer.). Como se ve, bsicamente la OOP lo que nos permite es ampliar los tipos de datos con los que vamos a trabajar: esto que dicho as, resulta tan tan simple, si lo piensa un poco, ver que es de una potencia nunca vista antes. Un objeto lo podemos considerar como un array multidimensional, donde se almacenan los datos de ese objeto (las coordenadas, el color, etc. en el ejemplo del marco) y sus mtodos, que no seran ms que punteros a funciones que trabajan con esos datos. De hecho, y para ser ms precisos, en el array de un objeto no se guardan los punteros a los mtodos de ese objeto, sino los punteros a otros arrays donde se hallan estas funciones, para ahorrar de este modo memoria. Tambin se guardan punteros a las clases superiores si las hubiese para buscar all los mtodos que no encontremos en la clase a la que el objeto pertenece: si un mtodo no es hallado en una clase, se supone que debe pertenecer a la clase padre (clase superior). A esto le llamamos herencia, pero de esto hablaremos extensamente ms adelante.
15
Ejemplo 5 Como hemos dicho, una clase es un nuevo tipo de dato y objetos son cada una de las asignaciones que hacemos a ese tipo de dato. En C un objeto lo podemos considerar como un Struct. Esta estructura albergara los datos del objeto, y los punteros a las funciones que formaran el conjunto de sus mtodos, ms otros punteros a las clases superiores (padre). Cada una de las instanciaciones (asignaciones) de variables que hagamos a un Struct, equivaldr a crear un nuevo objeto de una clase. Las clases aparecen en C como Structs muy mejoradas. De hecho, fueron los Structs quienes sugirieron y dieron lugar a las clases y son sus antecesores informticos. Para que entendamos hasta donde llega esta similitud, le informaremos que existe un programa que recibe un cdigo fuente hecho en C++ (C con OOP) y devuelve otro cdigo fuente equivalente al anterior, pero en C normal.
16
Solicita a tu profesor y descomprime el contenido del archivo Alife.zip en tu mquina. Haz clic en la opcin Load Content (cargar contenido) del men Actions (acciones) en la ventana del Workbench. Carga los archivos con extensin .html y .gif que extrajiste del archivo zip. De nuevo haz clic en la opcin Load Content (cargar contenido) del men Actions (acciones) en la ventana del Workbench y carga los archivos con extensin .class que extrajiste del archivo zip. Selecciona el archivo initialWorldAlgaeFishCroc.html en la ventana del Servlet Workbench y brelo con la opcin Open in Browser (abrir en el navegador) del men Actions.
Observa que el archivo initialWorldAlgaeFishCroc.html contiene una forma de HTML con una cuadrcula de 10 lneas, con 10 celdas cada una. Cada celda de la cuadrcula contiene tres controles de entrada de tipo checkbox, etiquetados como algae (alga), catfish (pez gato), y crocodile (cocodrilo). La forma tambin contiene un control de entrada de tipo cuadro de texto (textbox) debajo de la cuadrcula, etiquetado como Blocks of Time to Simulate (bloques de tiempo para la simulacin). Al final de la forma hay un botn llamado Start Simulation (iniciar simulacin). La cuadrcula de la forma modela bsicamente el cuerpo de agua en el lago. Por ahora, los organismos modelados son peces gato, algas y cocodrilos. Cada celda de la cuadrcula permite escoger cualquier combinacin de estos tres organismos. Uno de los objetivos de la simulacin es estudiar cmo el tamao y la densidad de las poblaciones afecta tanto el movimiento del pez gato y los cocodrilos como el crecimiento de las algas. Para lograr esto, correremos varias veces el programa de simulacin. Para cada iteracin, estableceremos las condiciones inciales del lago variando uno o ms de los siguientes aspectos: el nmero y la ubicacin de inicio de los peces gato, cocodrilos y algas.
17
Observaremos el comportamiento de los organismos al correr el programa de simulacin, sin embargo, antes te proporcionaremos cierta informacin que te ayudar a establecer la condicin inicial del lago:
Los peces gato pueden comerse las algas y los cocodrilos pueden comerse a los peces gato. Tanto los peces gato como los cocodrilos pueden desplazarse de celda a celda, mientras que las algas permanecen fijas. Las algas necesitan de la luz del sol para sobrevivir. El programa provee cantidades aleatorias de luz solar para cada celda. Tpicamente, 20-30 pasos de tiempo son suficientes comportamiento de los organismos y generar conclusiones. para observar el
Un pez gato, sin algas ni cocodrilos Un cocodrilo, sin algas ni peces gato nicamente algas, sin peces gatos ni cocodrilos Una colonia de algas, un par de peces gatos y un cocodrilo a cierta distancia de la colonia de algas.
La siguiente figura muestra cmo configurar las condiciones inciales del lago:
18
19
Una vez que hayas realizado varios experimentos sobre este modelo, trata de contestar las siguientes preguntas, haciendo uso de tus conocimientos sobre programas orientados a objetos: 1. Qu clases se requieren para construir un modelo como este para simular la vida de los organismos en un lago? 2. El programa de simulacin requiere siempre crear objetos de estas clases? Es decir, cmo afecta tu configuracin inicial la creacin de objetos por el programa? 3. Cmo puede afectar el nmero de organismos seleccionados en la configuracin inicial el nmero de objetos creados por el programa? 4. Cules seran los atributos de las clases que imaginaste en la pregunta #1? Sugerencia: necesitas observar la apariencia y conducta de los organismos modelados por la clase para deducir los atributos. Adems, necesitas tomar en consideracin toda la informacin que se te proporcion al inicio. Por ejemplo: saber que las algas requieren energa para vivir y el hecho de haber notado que algunas algas murieron durante la simulacin nos indica que la clase que modela al organismo "algas" requiere un atributo que represente la cantidad mnima de energa que stas requieren para permanecer con vida. 5. Puede cambiar la conducta del cocodrilo basada en la presencia o ausencia de peces gato? Puede el cocodrilo acercarse o alejarse de los peces? Crees que estas preguntas afectan la forma en que debe modelarse el organismo "cocodrilo"?
20
Del mismo modo, crees que la conducta del pez gato cambia dependiendo de la presencia o ausencia de algas? Puede el pez gato acercarse o alejarse de las algas? Crees que estas preguntas afectan la forma en que el pez gato debe ser modelado? Toma en cuenta que debers correr muchas veces la simulacin para poder contestar estas preguntas. Es aceptable si sientes que en este punto del curso no cuentas con la suficiente informacin para responder alguna pregunta en particular. Cuando trates de responderlas, te dars cuenta que las preguntas estn poniendo en prueba si entendiste la relacin entre clases y objetos, la estructura de un objeto y la organizacin de los programas orientados a objetos en cuanto a objetos que se comunican por medio de mensajes. Al ir avanzando en el curso, veremos con ms detalle cmo fue realizado en Java este programa de simulacin. De hecho, debers complementarlo (modelar organismos adicionales que viven en el lago) utilizando conceptos que aprenders a lo largo del curso. Para lograrlo, estudiaremos a continuacin cmo se escriben y ejecutan programas en Java.
21
Lectura. Core Java 2 Volumen 1 Fundamentos. Cay S Horstmann, Gary Cornell, Rearson Prentice Hall Septima Edicion. Cdigo Fuente Java.
Despues de que has hecho las lecturas de apoyo, es hora de comenzar a editar tus propios programas en Java, para este curso comenzaremos a trabajar con Servlet, para lo cual debemos aprender a editar el codigo fuente de estos. A continuacin se muestra el codigo fuente del servlet Welcome, el cual deberas de transcribir o copiar en un documento de texto dentro del block de notas, (es importante comenzar con el block de notas por que asi nos aseguraremos de no incluir elementos propios de un editor mas poderoso). Al archivo de codigo fuente le pondras el nombre Welcome.java (Pon atencion al escribir el nombre ya que mayusculas y minusculas deben coincidir con el nombre de la clase, si no coinciden, el servlet no funcionara.).
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: import java.io.*; import javax.servlet.*; import javax.servlet.http.*; public class Welcome extends HttpServlet { public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { /** * Indica el tipo de contenido (por ejemplo, texto/html),
22
12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27:
* que regresar la respuesta */ response.setContentType("text/plain"); /** * Llama a un flujo de salida que usa para enviar datos * al cliente */ PrintWriter out = response.getWriter(); /** * Escribe la respuesta */ out.println("Welcome to iCarnegie!"); } }
Cdigo Fuente 1
Welcome.java
Observa con atencin la forma en como esta estructurado el cdigo, considera la forma en como estn colocados los comentarios, la declaracin de variables, la creacin de mtodos y la importacin de libreras, ya que todo esta codificado siguiendo las normas de documentacin de Javadoc y las buenas costumbres de programacin.
23
Adems de agregar en el path la ruta para que reconozca donde se encuentra el compilador, debemos de tener acceso a el paquete que nos permitir generar la clase como un Servlet, esta se encuentra en la instalacin de workbench dentro de la carpeta lib, y el archivo se llama javax.servlet.jar, para este ejemplo, la carpeta de Workbench se encuentra en la raz del disco C:, este paquete lo direccionaremos mediante la variable de entorno Classpath, esto tambin lo haremos dentro de la pantalla de variables de entorno y creando la variable Classpath, se anexa pantalla.
24
Si no agregas a las variables de entorno el classpath y la ruta completa de javax.servlet.jar a la hora de hacer la compilacin resultara en un error como el siguiente
25
26
Como podrs observar en el cdigo de la pgina Web anterior, nos encontramos que el atributo action del elemento FORM del cdigo HTML se refiere al archivo de la clase servlet Welcome. <FORM action='/servlet/Welcome' method='post'>
27
54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73: 74: 75: 76: 77: 78: 79: 80: 81: 82: 83: 84: 85: 86 87: 88: 89: 90: 91: 92: 93: 94: 95: 96: 97: 98: 99: 100: 101: 102: 103: 104: 105: 106: 107: 108: 109:
* El rea para nadar est limitada por las fronteras del lago. * Si est en la frontera izquierda, no podr seguir nadando hacia la izq. * * @no regresa nada. */ public void swimLeftIfPossible() { //Si la celda izquierda est dentro de los lmites, se mueve a la izq. if (column - 1 >= 1) { column = column - 1; } imageFileName = "/Catfish-left.gif"; } /** * Nada una celda hacia abajo. * El rea para nadar est limitada por las fronteras del lago. * Si est en la frontera inferior, no podr seguir nadando hacia abajo. * * @no regresa nada. */ public void swimDownIfPossible() { //Si la celda inferior est dentro de los lmites, se mueve hacia abajo. if (row + 1 <= 10) { row = row + 1; } imageFileName = "/Catfish-down.gif"; }
/** * Nada una celda hacia arriba. * El rea para nadar est limitada por las fronteras del lago. * Si est en la frontera superior, no podr seguir nadando hacia arriba. * * @no regresa nada. */ public void swimUpIfPossible() { //Si la celda inferior est dentro de los lmites, se mueve hacia arriba. if (row - 1 >= 1) { row = row - 1; } imageFileName = "/Catfish-up.gif"; } /** * obtiene el nombre del archivo de la imagen del pez gato * * @regresa el nombre del archivo de la imagen del pez gato */ public String getImage() { return imageFileName; } }
Listado 2 Catfish.java
Escribe o copia y pega este cdigo fuente en un editor de textos y gurdalo en un archivo. Recuerda que el archivo fuente deber tener el nombre de Catfish.java, debido a que el nombre de la clase es Catfish, como puedes ver en la lnea 1 del listado. Ahora compila la Clase Catfish, t a estas alturas ya eres un experto. Catfish, no es la nica clase que utilizamos dentro del programa de simulacin, sin embargo, por el momento las otras clases contienen temas de programacin que escapan al objetivo de este curso, por lo tanto no las veremos en este momento.
28
Como ya sabrs para poder ejecutar la clase que acabas de compilar, hay que tener todo un proyecto completo que incluya una pgina web y las otras clases que acompaan a esta actividad, es por ello que debes solicitar a tu profesor las clases restantes. Descomprime el archivo que te ha sido entregado y despus de haber borrado los archivos que estaban contenidos dentro de las carpetas Java_Classes y Content que pertenecen a tu instalacin de Workbench, ahora copia los archivos html y de imagen que estn en el archivo comprimido que te acaban de entregar dentro de la carpeta Content, y los archivos .class adems del archivo catfish.class que acabas de compilar a la carpeta Java_Classes. Ejecuta workbench y en el directorio Content busca el archivo CreateFishes.html y da clic derecho sobre el y elige la opcin Open in Browser. La siguiente imagen es un ejemplo de cmo se vera tu navegador con la llamada a esta pagina.
Hasta este punto, has completado satisfactoriamente el desarrollo de un servlet y una clase de Java. Ya sabes cmo crear un archivo de cdigo fuente (.java) para un servlet de Java y cmo hacer la definicin de una clase para un objeto de Java. Tambin aprendiste cmo
29
compilar un archivo fuente de Java para obtener un archivo .class. Por ltimo, tambin sabes ya cmo ejecutar un servlet utilizando una forma de HTML y el iCarnegie Servlet Workbench..
Clase CatFish
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 31: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47:
public class Catfish { /** * Ubicacin del pez gato - en qu fila. */ private int row; /** * Ubicacin del pez gato - en qu columna. */ private int column; /** * Imagen del pez gato - en realidad es un nombre de archivo. */ private String imageFileName; /** * Ubicacin del pez gato - fila * * @return - un entero que representa la fila donde se ubica el pez */ public int getRow() { return row; } /** * Ubicacin del pez gato - columna * * @return - un entero que representa la columna donde se ubica el pez */ public int getColumn() { return column; } /** * Nada una celda hacia la derecha. * El rea para nadar est limitada por las fronteras del lago. * Si est en la frontera derecha, no podr seguir nadando hacia la derecha */ public void swimRightIfPossible() { //Si la celda derecha est dentro de los lmites, se mueve a la derecha if (column + 1 <= 10) { column = column + 1; } imageFileName = "/Catfish-right.gif";
30
48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73: 74: 75: 76: 77: 78: 79: 80: 81: 82: 83: 84: 85: 86: 87: 88: 89: 90: 91: 92: 93: 94: 95: 96: 97: 98: 99: 100: 101:
} /** * Nada una celda hacia la izquierda. * El rea para nadar est limitada por las fronteras del lago. * Si est en la frontera izquierda, no podr seguir nadando hacia la izq. */ public void swimLeftIfPossible() { //Si la celda izquierda est dentro de los lmites, se mueve a la izq. if (column - 1 >= 1) { column = column - 1; } imageFileName = "/Catfish-left.gif"; } /** * Nada una celda hacia abajo. * El rea para nadar est limitada por las fronteras del lago. * Si est en la frontera inferior, no podr seguir nadando hacia abajo. */ public void swimDownIfPossible() { //Si la celda inferior est dentro de los lmites, se mueve hacia abajo. if (row + 1 <= 10) { row = row + 1; } imageFileName = "/Catfish-down.gif"; }
/** * Nada una celda hacia arriba. * El rea para nadar est limitada por las fronteras del lago. * Si est en la frontera superior, no podr seguir nadando hacia arriba. */ public void swimUpIfPossible() { //Si la celda inferior est dentro de los lmites, se mueve hacia arriba. if (row - 1 >= 1) { row = row - 1; } imageFileName = "/Catfish-up.gif"; } /** * obtiene el nombre del archivo de la imagen del pez gato * * @return el nombre del archivo de la imagen del pez gato */ public String getImage() { return imageFileName; } }
Como recordaras en las lecturas previas que has hecho, una clase Java se compone de diferentes componentes como lo son Identificadores, Estructuras de Control, Formato y Comentarios, es hora de analizar cada uno de estos componentes dentro del cdigo anterior. El listado anterior contiene muchos comentarios dentro de su estructura, estos comentarios son importantes ya que nos indican las actividades que realizaran la clase y/o los mtodos.
/** * Nada una celda hacia la derecha. * El rea para nadar est limitada por las fronteras del lago. * Si est en la frontera derecha, no podr seguir nadando hacia la derecha **/
31
Lo anterior es un ejemplo de cmo debe establecerse un comentario de varias lneas, estos generalmente se usan para comentar una clase o un mtodo. Dentro del listado, tambin encontramos algunas palabras reservadas como las siguientes class public return if else void. Dentro del listado, estas clases han sido escritas en color azul. Tambin dentro del cdigo fuente anterior se encuentran algunos atributos (identificadores) y/o mtodos, los cuales son: imageFileName row column getImage getColumn String
Definiendo Clases. Recordando la definicin que se encuentra en la lectura introduccin a java, en donde se nos explicaba que para crear un objeto, requerimos primero de la especificacin de la clase, ya que en java, una clase se convierte en un tipo de dato, a partir del cual, nosotros podemos crear objetos, cuando creamos un objeto, tambin se le conoce como instancia de una clase. El listado anterior nos da la descripcin de la clase CatFish, a esta descripcin se le llama definicin de clase, La informacin que obtenemos de esta descripcin es la siguiente. La lnea numero uno del cdigo fuente nos dice el nombre de la clase y su accesibilidad, aqu nos encontramos con la siguiente definicin public class CatFish, donde public nos indica que ser una clase publica y cualquiera que tenga acceso a su ubicacin podr hacer uso de ella, tambin el que sea public obliga a que el archivo que contenga a esta clase, debe de llamarse de la misma manera que la clase. La palabra reservada class nos indica que estamos declarando una clase, y CatFish, es asignado como identificador de esta clase. El contenido de la clase esta delimitado por {} (Llaves), las cuales marcan el inicio y fin de la clase, como podrs ver el contenido de la clase inicia en la lnea uno con unas { justo despus de la declaracin de la clase, estas llaves son cerradas hasta la lnea 101, que es donde se termina esta clase. El contenido de absolutamente todos los elementos que forman la clase esta dentro de las llaves, no puede existir ningn elemento fuera de estas llaves. 32
Atributos de la clase. Las instrucciones de las lneas 6, 11 y 16 son los atributos de objeto de la clase Catfish (Variables de instancia). Los estatutos de las lneas 6 y 11 describen los atributos que corresponden a la fila y a la columna, respectivamente, en la cuadrcula donde se ubica el pez. El estatuto de la lnea 16 describe el atributo que corresponde al nombre del archivo de imagen utilizado para representar al pez en un momento dado.
6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: private int row; /** * Ubicacin del pez gato - en qu columna. */ private int column; /** * Imagen del pez gato - en realidad es un nombre de archivo. */ private String imageFileName;
Se puede observar que los tres atributos tienen al inicio la palabra reservada de java prvate esta palabra indica que estos atributo solo pueden ser laidos u modificados desde la clase catfish, dentro de algn mtodo. Las palabras int y String, son otras palabras reservadas de java, estas palabras indican el tipo de dato que estar asociado con el atributo, la palabra int se refiere a un numero entero de 32 bits con signo, y la palabra String a un objeto de tipo cadena de caracteres en el cual podremos almacenar textos.. Los estatus imageFileName, row y column, son los nombres de los atributos. La ltima palabra de estos estatutos es el nombre en s del atributo: row, column e imageFileName.
Comportamiento de las clases Despus de la declaracin de los atributos, nos encontramos con varios mtodos, los cuales describen la funcionalidad de la clase catfish, los mtodos con los que cuenta la clase son: getRow getColumn getImage swimRightIfPossible swimLeftIfPossible swimUpIfPossible 33
swimDownIfPossible
Los mtodos son conocimos como mensajes, el formato de respuesta de y la forma de llamarlos viene dada en la descripcin del mensaje, tomando como ejemplo el mensaje swimLeftIfPossible que se encuentra definido en la lnea 54, nos encontramos con la siguiente definicin.
55: 56: 57: 58: 59: 60: 61: 62: public void swimLeftIfPossible() { //Si la celda izquierda est dentro de los lmites, se mueve a la izq. if (column - 1 >= 1) { column = column - 1; } imageFileName = "/Catfish-left.gif"; }
La definicin del mtodo anterior, nos indica primero, que el mtodo es publico, es decir, que podr ser accedido o invocado desde cualquier objeto hecho a partir de la clase, la palabra reservada void, nos indica el tipo de respuesta que dar el mensaje, con un void, indica que no dar respuesta alguna, sino que solo har alguna actividad y probablemente modificara un atributo, en lugar de void, se podra tener a int, String, double o cualquier otro tipo de dato que se pueda devolver como respuesta a la llamada del mtodo. Despus de definir el tipo de dato del que ser la respuesta del mtodo, se escribe el nombre del mtodo en este caso es swimLeftIfPossible, despus del nombre del mtodo, podemos conservar unos parntesis que se abren y cierran, estos son parte de la definicin del mtodo y son obligatorios, en algunas ocasiones dentro de estos parntesis incluimos parmetros o argumentos que son necesarios para que la tarea del mtodo sea completada. Las siguientes observaciones te ayudarn a examinar las definiciones de los mtodos para los dems mensajes del listado:
Los nombres de los mensajes pueden caer en dos categoras. Una de ellas sigue el patrn get* y la otra, el patrn swim*IfPossible. Estos nombres deben ser lo suficientemente representativos del comportamiento de las definiciones de mtodos respectivas. El primer grupo de mensajes permite que cualquier otro objeto se comunique con los objetos tipo para obtener Catfish informacin sobre sus atributos. Por ejemplo, el mensaje getRow permite que otros mensajes se comuniquen para averiguar en qu lnea de la cuadrcula se encuentra el objeto Catfish. El segundo grupo de mensajes intenta modificar el objeto Catfish para que nade en una direccin en particular. Por ejemplo, el mensaje swimRightIfPossible describir la conducta de los objetos tipo Catfish que intenten nadar hacia la derecha de la cuadrcula. Los nombres de los mensajes siguen cierta convencin, donde el nombre utiliza palabras que expresan el propsito de la conducta. La primera letra de cada palabra (exceptuando la primera) debe estar en maysculas. Esta es una convencin para programacin en Java. Aprenderemos sobre estas convenciones ms adelante en el curso. Por ahora, toma nota: dichas convenciones hacen que el cdigo fuente sea ms fcil de leer y entender. Aunque nosotros no escribimos el cdigo fuente de la clase Catfish, podemos entender sus partes con simplemente leerlo.
34
Los mensajes que siguen el patrn get* regresan algo al terminar su ejecucin, mientras que los que siguen el patrn swim*IfPossible no regresan ningn valor.
Un buen auxiliar en el anlisis y el diseo de programas orientados a objetos, son los diagramas de clases, estos nos ofrecen una forma grafica de representar una clase, a continuacin se da el ejemplo de cmo debe ser la forma grafica de la clase CatFish
La informacin que contiene el diagrama anterior puede ser ampliada si consideramos que conocemos los tipos de datos de los atributos y los tipos de datos que devolvern los mtodos, as pues si agregamos esta informacin al diagrama quedara de la siguiente manera
Trabajando con la sentencia if Cuando se hace una llamada a un mtodo dentro de un objeto, las instrucciones contenidas dentro del mtodo se ejecutan de manera secuencial, en el orden en que aparecen, Sin embargo, en ocasiones, no queremos que todas las instrucciones sean ejecutadas, o queremos que las instrucciones sean ejecutadas de manera selectiva, solamente cuando ciertas condiciones son verdaderas o falsas. Para cuando se requiere una ejecucin selectiva, vamos a tener la sentencia condicional if
35
Ejemplo: De
swimRightIfPossible (ver Secuencia de ejecucin de una sentencia if Listado 1, iniciando en la lnea 43)
En el mtodo swimRightIfPossible (ver Listado Catfish, lnea 44), decimos que el nadar a la derecha debe condicionarse para que el pez gato se mantenga dentro de los lmites. De esta forma, utilizamos una sentencia if para ejecutar condicionalmente la instruccin de nadar a la derecha. La sentencia if comprueba si el nuevo valor del atributo column es menor o igual a 10 (el lmite del lago). La comprobacin es expresada dentro de parntesis: (column + 1 <= 10) (ver lnea 46). Nadar a la derecha se lleva a cabo al incrementar el valor del atributo column: column = column + 1; (ver lnea 47). El bloque de instrucciones que debe ejecutarse condicionalmente estn encerrados entre llaves: {}. En este caso, el bloque consiste de una sola instruccin (lnea 47). En esta seccin hemos examinado el cdigo fuente de una clase simple de Java. En el proceso, estudiamos cmo una definicin de clase en Java describe los atributos y la conducta del objeto. Tambin hemos visto cmo podemos modificar la definicin de clase.
36
A partir de este cdigo, hay que examinar cada uno de los elementos que forman parte del servlet. El cdigo esta repleto de comentarios que documentan su comportamiento, asi pues existen comentarios en las lneas 1-5, 15-18, 21-23 y 26-28. Eliminando los comentarios el cdigo contiene los siguientes estatutos
import java.io.*;
37
import java.servlet.*; import java.servlet.http.*; response.setContentType("text/plain"); PrintWriter out = response.getWriter(); out.println("Bienvenido a Informatica!");
Analizando en profundidad
Los primeros estatutos con los que cuenta el cdigo, los que estn en las lneas 6-8 encontramos las sentencias import java.io.*; import javax.servlet.*; e import javax.servlet.http.*;. Estas sentencias importan las libreras necesarias para la ejecucin de los servlets,
38
La primera sentencia import java.io.*, hace posible el uso de los objetos y los mtodos de entrada y salida de datos, por ejemplo el uso y la creacin de objetos PrintWriter, o las llamadas al mtodo println. El segundo y tercer estatuto import javax.servlet.*; e import javax.servlet.http.*; contienen las clases abstractas necesarias para que los servlets puedan especificar que tipo de protocolo usaran, y tambin el formato de los mtodos bsicos de un servlet.
Despues de las hacer la importacin de las libreras, se encuentra la declaracin de la clase Welcome, que es como se llama el servlet y es como se deber llamar el archivo del servlet,. ( a partir de esta clase se creara el objeto, que es el que llama el servidor de servlets)., la declaracin de la clase se hace de la siguiente manera
public class Welcome extends HttpServlet {
En esta definicin de la clase contiene primeramente las palabras reservadas public class que indican que estamos definiendo una clase publica, despus de estas palabras reservadas (las cuales deben de contener cada uno de los servlets que construyas), se encuentra el identificador o nombre de la clase el cual para este ejemplo es Welcome. Adelante del identificador de la clase se encuentran las palabras extends HttpServlet, estas palabras son necesarias para cada servlet que se construya, mas adelante en el curso se explicara que significa extends, por ahora solo se dira que HttpServlet es una clase que indica y da la funcionalidad a un servlet basado en http. Para terminar esta lnea nos se encuentran un abrir llaves { estas engloban donde comienza una definicin de clase, y se cierran hasta la lnea 31 que es donde termina la clase. En la lnea 11 de cdigo se encuentra la definicin del mtodo doPost, el cual tiene el siguiente aspecto public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
El mtodo es invocado por el servidor a travs del mtodo service() (El cual no trataremos en este materia, es interno del servidor web), para permitir que el servlet trate una peticin POST. Este mtodo es de los tpicos que podemos encontrar en un servlet. Los recursos por el mensaje doPost requeridos (parmetros del mtodo) estn especificados en el siguiente cdigo: HttpServletRequest request, HttpServletResponse response.
Estos parmetros indican que request (peticin) y response (respuesta) son objetos de las clases HttpServletRequest y HttpServletResponse, respectivamente. Las libreras que se importaron en las lneas 7 y 8 contienen a estas clases. Cuando el mensaje doPost es recibido por el servlet, el objeto request habilita el servlet para que pueda tener acceso a toda la informacin relacionada con la peticin del navegador que invoc el servlet, incluyendo la entrada del usuario enviada junto con la forma de HTML. El objeto response habilita el servlet para enviar su respuesta de vuelta al navegador. La especificacin de este mtodo siempre contendr la misma forma, por lo que en este punto es suficiente con que conozcas estos estatutos, y hay que recordar siempre poner el mtodo doPost, tal cual como se muestra en esta ocasin. Para finalizar con la especificacin de doPost resta comentar que al igual que en la definicin de la clase, delimitamos el contenido de este mtodo mediante las llaves, que en esta ocasin son abiertas en la lnea 13 y cerradas en la lnea 30.
39
Cuando ya se ha hecho la declaracin del mtodo doPost, y despus de los comentarios se encuentra lnea 19, la cual tiene la siguiente instruccin response.setContentType("text/plain");
Esta instruccin debe de ser de los primeros pasos del mtodo doPost y sirve para informar al navegador que lo que debe esperar del servidor es texto plano. Por lo que, el servlet enva el mensaje setContentType al objeto response, El mensaje setContentType requiere un recurso para ejecutarse; este recurso es especificado por el cdigo "text/plain", que indica que el servlet generar texto plano. Por otra parte, un servlet que genera una pgina HTML debe especificar el cdigo "text/html" al enviar el mensaje setContentType y si se trata de un servlet que genera un archivo GIF, deber especificar lo siguiente: "text/gif". Ya definido el formato de respuesta, hay que habilitar algunos otros elementos, para el caso de este cdigo, hay que habilitar el flujo de salida (Objeto que usaremos para escribir texto), esto se hace mediante la siguiente instruccin. PrintWriter out = response.getWriter();
En el cdigo anterior, se esta haciendo lo siguiente: Se crea una referencia a un objeto PrintWriter llamada out, PrintWriter es parte de la librera IO y sirve para poder abrir un flujo de salida a un dispositivo, en este caso ser la pgina Web con las que responderemos al servidor Web. El mtodo getWriter del objeto response, asignara a la referencia out el flujo de salida de los datos que nosotros enviemos mediante el objeto out.
En este paso ya que se ha definido el tipo de respuesta que tendr el servlet al ser invocado, y despus de haber preparado el objeto que permitir escribir el resultado, ha llegado el momento de mandar texto como respuesta de la ejecucin del servlet. La respuesta se hara usando un mtodo de escritura en una salida de datos, esto se hace con la siguiente instruccin. out.println("Bienvenido a Informatica!");
La instruccin anterior hace lo siguiente: Usando el objeto out de tipo PrintWriter, invoca al mtodo println (Imprime) envindole el texto que se quiere sea devuelto como respuesta a la llamada del servlet, de esta manera el resultado de invocar el servlet es devuelto al navegador que hizo la llamada y se muestra el resultado. Ahora practica la invocacin de este cdigo, y trata de hacer modificaciones para que arroje diferentes resultados. Recuerda, tienes que hacer la pgina Web que lo invoque, y debes usar el workbench. Devolviendo una pagina Web
Examinemos ahora una variacin del servlet Welcome. Esta variacin enviar una pgina Web en HTML al navegador, en vez de texto plano. Lo primero que debemos hacer, es asegurarnos que el navegador sabe sobre este cambio. Como vimos hace un mo, mento en la descripcin de la lnea 19 del Listado 1, necesitamos 40
especificar el parmetro "text/html" en vez de "text/plain" al enviar el mensaje setContentType al objeto response. Esta lnea se ver as:
response.setContentType("text/html");
Para enviar una pgina Web en HTML desde el servlet, el servlet necesita bsicamente exportar todo el cdigo HTML de la pgina Web al navegador. Resulta til escribir primero el cdigo HTML para la pgina Web. Ahora sabes (como viste en la Unidad 1) que para que una pgina Web despliegue nuestro mensaje de bienvenida del Listado 1, el cdigo HTML deber ser como se indica a continuacin:
<!DOCTYPE HTML PUBLIC '-//W3C//DTD HTML 4.01 Transitional//EN'> <HTML> <HEAD> <TITLE> Welcome </TITLE> </HEAD> <BODY> Bienvenido a Informtica! </BODY> <HTML>
Para enviar una pgina web, el servlet requiere, principalmente, enviar el mensaje println al objeto out para cada lnea de cdigo HTML enviada al navegador. Esto es equivalente a usar el estatuto de la lnea 31 del Listado 1. Al hace esto, el cdigo fuente del servlet presentado en el Listado 1 se ver como se presenta a continuacin:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 /** * Autor: ISI * Fecha: Agosto 2009 * Descripcin: Servlet que despliega un mensaje de bienvenida. */ import java.io.*; import javax.servlet.*; import javax.servlet.http.*; public class HtmlWelcome extends HttpServlet { public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { /** * Indica el tipo de contenido (por ejemplo, text/html), * que ser regresado como respuesta */ response.setContentType("text/html"); /** * Regresa un flujo de salida usado para enviar datos al cliente */ PrintWriter out = response.getWriter(); /** * Escribe la respuesta */ out.println( "<!DOCTYPE HTML PUBLIC '-//W3C//DTD HTML 4.01 Transitional//EN'>"); out.println("<HTML>"); out.println("<HEAD>"); out.println("<TITLE>"); out.println("Bienvenido"); out.println("</TITLE>"); out.println("<BODY>"); out.println("Bienvenido a Informatica!"); out.println("</BODY>"); out.println("</HTML>"); } }
41
Nota que la lnea 10 ahora nos indica que el nombre del servlet es HtmlWelcome. Bsicamente, hemos creado un nuevo servlet. Si has trabajado con las instrucciones para desarrollar el servlet, a continuacin hay un ejercicio ms que te sugerimos intentar:
Copia el cdigo fuente del Listado 2 en un archivo llamado HtmlWelcome.java. De nuevo, toma en cuenta que los nmeros de lnea son nicamente un apoyo para ti, por lo que no debers incluirlos en tu archivo fuente. Compila el archivo HtmlWelcome.java. Ahora tienes un nuevo servlet HtmlWelcome en el archivo HtmlWelcome.class, el cual enva el mismo mensaje de bienvenida que el servlet Welcome, pero lo enva como parte de una pgina Web en vez de texto plano. Ahora requerimos una nueva forma para invocar el servlet HtmlWelcome; esta forma puede ser una copia de la forma que empleamos para invocar el servlet Welcome. Entonces, realiza una copia del archivo WelcomeForm.html y llmalo HtmlWelcomeForm.html. Edita el archivo HtmlWelcomeForm.html de modo que el atributo action del elemento FORM del archivo invoque al servlet HtmlWelcome en vez del servlet Welcome. Ejecuta el servlet HtmlWelcome. Toma en cuenta que debers cargar los archivos HtmlWelcome.class y HtmlWelcomeForm.html en el Workbench.
El mensaje desplegado en el navegador no se ver diferente al enviar las formas de los archivos WelcomeForm.html y HtmlWelcomeForm.html. Sin embargo, si abres el men View (ver) del navegador y selecciones la opcin Source (fuente) en ambos casos, en el primero desplegar nicamente el mensaje Bienvenido a Informtica!, mientras que en el segundo vers el cdigo HTML que escribimos al editar el servlet Welcome:
<!DOCTYPE HTML PUBLIC '-//W3C//DTD HTML 4.01 Transitional//EN'> <HTML> <HEAD> <TITLE> Bienvenido </TITLE> </HEAD> <BODY> Bienvenido a Informtica! </BODY> <HTML>
Por lo tanto, al escribir servlets que envan pginas Web al navegador, resulta una buena idea implementar el cdigo HTML de la pgina Web antes de escribir los estatutos out.println en el archivo fuente del servlet. Por ejemplo, considera un caso en el que el servlet enva una imagen en vez de desplegar un mensaje de bienvenida. El cdigo HTML para la pgina Web se ver muy similar a lo que presentamos a continuacin:
42
<!DOCTYPE HTML PUBLIC '-//W3C//DTD HTML 4.01 Transitional//EN'> <HTML> <HEAD> <TITLE> Bienvenido </TITLE> </HEAD> <BODY> <IMG src = '/sf.jpg' alt='San Francisco'> </BODY> <HTML>
Entonces, necesitaremos cambiar la lnea 37 del listado 2. Siguiendo la regla de que el texto debe ser desplegado por el mtodo println entre comillas (" "), la lnea 37 deber ser como se indica a continuacin:
out.println("<IMG src='/sf.jpg' alt='San Francisco'>");
Si has estado trabajando con el ejemplo HtmlWelcome, te presentamos algo que podrs probar tambin:
Edita el archivo HtmlWelcome.java para que despliegue una imagen en vez de un mensaje de texto. Entonces, cambia la lnea 37 como mostramos anteriormente. Toma en cuenta que estamos utilizando el archivo de imagen sf.jpg. Puedes usar cualquier archivo de imagen que tengas disponible. Asegrate de cambiar la especificacin del atributo alt de acuerdo a tu archivo. De nuevo, te recordamos que es buena idea escribir el cdigo HTML que ser enviado por el servlet antes de cambiar el archivo fuente del servlet. Compila el archivo HtmlWelcome.java. Ahora cuentas con una nueva versin del servlet HtmlWelcome en el archivo HtmlWelcome.class; este servlet enva una imagen como parte de una pgina Web en vez de un mensaje de texto. Ejecuta la nueva versin del servlet HtmlWelcome Toma en cuenta que debers cargar la nueva versin del archivo HtmlWelcome.class en el Workbench. Tambin debers cargar la imagen que ests utilizando en el directorio HTML del workbench, si an no lo has hecho. Puedes utilizar la misma forma empleada en la versin anterior del servlet HtmlWelcome.
Recibiendo Entrada del Usuario An y cuando la forma WelcomeForm.html nos permita introducir un nombre, el mensaje enviado por el servlet Welcome no tena nada que ver con el nombre introducido por el usuario. Esto se debe a que el cdigo fuente del servlet Welcome que examinamos no intentaba averiguar qu haba introducido el usuario para incluirlo en la informacin de la pgina Web enviada al navegador. Cuando un servlet es invocado por una forma, hay una forma de que el servlet obtenga la entrada del usuario especificada en la forma. Para hacer esto, el servlet necesita enviar el mensaje getParameter a request, que es un objeto de HttpServletRequest. Por lo tanto, necesitaremos agregar una nueva lnea de cdigo a nuestro Listado 1 como se indica a continuacin: 43
Cuando el objeto request procesa el mensaje getParameter, el resultado es una instancia de la clase String, identificada por el nombre userName. El mensaje getParameter toma el parmetro "Name", que identifica el nombre del control de entrada de texto de la forma que se encuentra en la pgina WelcomeForm.html. Tambin necesitamos modificar la lnea 29 del Listado 1 para desplegar el nombre de la salida HTML. La nueva lnea 29 quedara as:
out.println("Bienvenido a Informtica, " + userName + "!");
Observa que el parmetro del mensaje println enviado al objeto out ha cambiado. En vez de un par de comillas delimitando el mensaje de bienvenida, ahora cuenta con tres partes, separadas por el carcter "+": "Bienvenido a Informtica, ", userName y "!". Aqu creamos una nueva cadena de caracteres aplicando la concatenacin de cadenas de caracteres que vimos en la Seccin 2.7 del libro de texto. En esta caso en particular, nos interesa crear una cadena de caracteres que se vea as:
Bienvenido a Informtica, John Doe!
donde "John Doe" es el valor obtenido utilizando el estatuto getParameter anteriormente. Por lo tanto, el estatuto anterior construye una cadena de caracteres concatenando o uniendo cadenas de caracteres ms pequeos, utilizando el operador "+" y sustituyendo el nombre del usuario por la cadena de caracteres. El Listado 3 muestra el cdigo fuente de un nuevo servlet, PersonalWelcome. En su mayora, se ve muy similar al Listado 1 del servlet Welcome, excepto que PersonalWelcome enva un mensaje personalizado, obtenido de la forma que lo invoca, como se presenta en la lnea 34.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 /** * Autor: ISI * Fecha: Agosto 2009 * Descripcin: Servlet que despliega un mensaje de bienvenida personalizado. */ import java.io.*; import javax.servlet.*; import javax.servlet.http.*; public class PersonalWelcome extends HttpServlet { public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { /** * Indica el tipo de contenido (por ejemplo, text/html), * regresado como respuesta */ response.setContentType("text/plain"); /** * cliente */ PrintWriter out = response.getWriter();
44
26 27 28 29 30 31 32 33 34 35 36
/** * Obtiene de la forma la entrada del usuario */ String userName = request.getParameter("Name"); /** * Escribe la respuesta */ out.println("Bienvenido a Informatica, " + userName + "!"); } }
Copia el cdigo fuente del Listado 3 en un archivo llamado PersonalWelcome.java. Una vez ms, ten en cuenta que los nmeros de lnea son slo un apoyo para ti, por lo que no debers copiarlos en el archivo fuente. Compila el archivo PersonalWelcome.java. Ahora tienes un nuevo servlet llamado PersonalWelcome en el archivo PersonalWelcome.class, el cual enva el mismo mensaje de bienvenida que el servlet Welcome, pero tambin incluye el nombre del usuario. Ahora requerimos una nueva forma para invocar el servlet PersonalWelcome; puede ser una copia de la forma que utilizamos para invocar el servlet Welcome. Entonces, haz una copia del archivo WelcomeForm.html y llmalo PersonalWelcomeForm.html. Edita el archivo PersonalWelcomeForm.html de modo que el atributo action del elemento FORM de dicho archivo invoque el servlet PersonalWelcome en vez del servlet Welcome. Ejecuta el servlet PersonalWelcome. Toma en cuenta que debers cargar los archivos PersonalWelcome.class y PersonalWelcomeForm.html en el Workbench.
45
Depurando (debugging) un Servlet Algunas veces, necesitars monitorear la ejecucin de un servlet. Esto podra ser til cuando requieras encontrar un error en el cdigo del servlet. Este error puede ser un error en tiempo de ejecucin, El Listado 4 muestra el cdigo fuente para el servlet Welcome, que tiene estatutos System.out.println adicionales en las lneas 24 y 34. Estos dos estatutos despliegan informacin sobre qu tanto ha progresado la ejecucin del servlet en la ventana de la consola del workbench, como se muestra en la siguiente imagen de pantalla. Observa que estos estatutos utilizan System.out.println en vez de out.println. Como se vio en la Seccin 1.5 del libro de texto, ambos estatutos envan un mensaje println al objeto System.out, con una cadena de caracteres que especifica la informacin que ser desplegada.
46
En esta seccin examinamos a detalle el cdigo fuente de una servlet simple. Esencialmente, esto implic entender cmo procesa el servlet un mensaje doPost. Tambin vimos algunas variaciones de este servlet, tal como enviar una pgina Web con una imagen y obtener la entrada del usuario a partir de la forma que invoca el servlet. En el proceso, vimos cmo los servlets generan pginas HTML dinmicamente (esto es, generando HTML basado en la entrada del usuario). Examinar las diferentes variaciones del servlet nos ha mostrado realmente cmo podemos cambiar la manera en que el mensaje doPost es procesado por el servlet. En la siguiente seccin, trabajaremos con un ejemplo que utiliza dichas variaciones.
47
La(s) entrada(s) del usuario enviada por la forma de HTML El formato y los contenidos de la pgina Web que ser generada por el servlet en respuesta, despus de procesa la(s) entrada(s) del usuario
Consideremos ahora la tarea de desarrollar un servlet de Java para manejar una de las formas del sitio Web de una agencia de viajes. A los usuarios que buscan informacin sobre algn destino de viaje se les presentar esta forma cuando visiten el sitio Web de la agencia. La forma permite a los usuarios introducir su nombre, nmero de telfono y una opcin de destino de viaje. El servlet invocado por la forma responde con una pgina Web que despliega la confirmacin de la peticin de informacin del usuario, as como una foto del destino seleccionado. Para empezar, tenemos una forma en un archivo de HTML y una plantilla de un archivo .java, que utilizaremos para escribir el servlet.
Pensando en el Futuro
Cuando se empiece a pensar en escribir el servlet, lo primero que hay que asegurar en que la PC cuente con lo siguiente:
El J2SE SDK est correctamente instalado en la PC y que eres capaz de compilar un servlet de Java. Toma en cuenta que esto requiere que el archivo javax.servlet.jar se encuentre en el workbench y adems este agregado en el classpath El Workbench est correctamente instalado en la PC, para invocar los servlets en el servidor Web incluido en la instalacin del mismo.
Antes de empezar a crear una solucin a la especificacin se debe de considerar que intentar empezar a escribir el cdigo antes de darle un vistazo a la especificacin o "brincarte a la codificacin" como se conoce comnmente, no es un buen hbito para un programador. La mayora de las veces esto puede llevarnos a consumir ms tiempo y esfuerzo en la programacin y, generalmente, no es la mejor solucin. Esto se debe a la falta de planeacin y estructura.
48
Un control de entrada de texto de una lnea, llamado telefono Un control de entrada de tipo botn de radio llamado destino y que tiene tres opciones: New York Monterrey Guadalajara Un botn de envo etiquetado como Peticin Informacin
o o o
Adems, el elemento FORM que se encuentra en el archivo FormaPeticion.html los mtodos action '/servlet/PeticionViaje' y post. Un ejemplo de la imagen en pantalla de dicha forma sera as:
49
Nuestra meta es desarrollar un servlet llamado PeticionViaje que procese la entrada del usuario a partir de la forma del archivo FormaPeticion.html. El servlet responde con una pgina HTML en Web que despliega la siguiente informacin:
Un mensaje de confirmacin que incluye el nombre del usuario obtenido de la forma y que adems informa que l o ella ser contactado pronto Una imagen de algn lugar o edificio muy conocido del lugar destino seleccionado por el usuario en la forma
Un ejemplo de la imagen en pantalla de la pgina Web que ser generada por el servlet se presenta a continuacin
50
A continuacin se encuentra un esqueleto del archivo java que se puede utilizar como plantilla para codificar el servlet. El archivo tiene comentarios que nos guiarn por varias tareas que el servlet debe realizar. Tambin cuenta ya con algo de cdigo del servlet
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 /** * Autor: * Fecha: * Descripcin: * */ import java.io.*; import javax.servlet.*; import javax.servlet.http.*; public class PeticionViaje extends HttpServlet { public void doPost( HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
51
18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64
/** * Indica el tipo de contenido (por ejemplo, text/html), * regresado en respuesta */ response.setContentType("text/html");
/** * Recibe un flujo de salida usado para enviar datos * al cliente */ PrintWriter out = response.getWriter();
: nombre y destino
/** * Comienza por escribir el encabezado de la pgina Web */ /* Agrega aqu tu cdigo */
} // end-doPost }
Planeando la Solucin
A partir de los comentarios del archivo plantilla java, concluimos que el servlet debe realizar las siguientes tareas: 1. Indicar el tipo de contenido que ser regresado como respuesta 2. Obtener un flujo de salida para enviar los datos al cliente 3. Obtener de la forma la entrada del usuario: nombre y destino
52
4. Empieza la pgina Web construyendo el encabezado de la misma 5. Aade la imagen 6. Aade el mensaje de confirmacin, con el nombre 7. Termina la pgina Web construyendo el pie de pgina Al examinar el archivo plantilla .java mostrado anteriormente, podemos observar unas cuantas lneas de texto o estatutos que provistas por los pasos 1 y 2. Entonces, necesitamos escribir solamente el cdigo para los pasos del 3 al 7. De los ejemplos de servlets vistos hasta el momento, sabemos que esta parte del servlet construir la pgina Web que ser enviada al navegador. Claramente, los dos componentes principales de esta pgina Web son el mensaje de confirmacin (incluyendo el nombre introducido por el usuario) que depende de uno de los controles de entrada de texto de la forma FormaPeticion.html, y una imagen, que depende del control de botn de radio de la forma que se encuentra en FormaPeticion.html. Debido a que la pgina generada por el servlet no despliega el nmero de telfono introducido por el usuario, el servlet no necesita preocuparse por obtener esta informacin de la forma. Por tal razn el archivo plantilla slo menciona el nombre y el destino. El servlet necesita obtener de la forma, solo dos de las tres entradas del usuario: el nombre y el destino.
Descubrimos en el ejemplo del servlet PersonalWelcome cmo obtener la entrada del usuario a partir de una forma de HTML: enviando el mensaje getParameter al objeto HttpServletRequest. En primer lugar, el control de la entrada de botn de radio de la forma tiene tres opciones que son nombres de ciudades. El servlet necesita saber qu ciudad fue seleccionada por el usuario y entonces elegir el archivo de la imagen correspondiente para incluirlo en la pgina que generar. El cdigo HTML de la forma FormaPeticion.html muestra que el valor del control de botn de radio llamado Destino regresa la eleccin del usuario sobre la ciudad destino. Tambin muestra que seleccionar en la forma New York, Monterrey o Guadalajara regresa los valores ny.jpg, mt.jpg, o gdl.jpg, respectivamente. El conocimiento adquirido nos ayuda a enviar el mensaje getParameter al objeto HttpServletRequest para obtener el valor del control de entrada de botn de radio Destino en la forma, nos brinda el nombre del archivo de la imagen de la ciudad destino seleccionada. Despus, el cdigo HTML de la forma en FormaPeticion.html nos muestra que el control de entrada de texto Nombre regresa el nombre del usuario. Una vez ms, para obtener de la forma el nombre del usuario, necesitamos enviar el mensaje getParameter al objeto HttpServletRequest, para obtener el valor del control de entrada de texto Nombre.
Pensemos ahora en cmo el servlet generar la pgina Web basndose en las entradas del usuario obtenidas de la forma.
El servlet debe generar la salida de todo el cdigo HTML para la pgina Web. Para desplegar la imagen de la ciudad destino, el cdigo HTML necesita una etiqueta IMG que utiliza la especificacin del archivo de imagen obtenido al procesar la entrada del usuario en la forma. Adems, para desplegar el mensaje de confirmacin con el nombre del usuario, el cdigo HTML deber incluir una lnea de texto que es la concatenacin del texto del mensaje con el nombre del usuario.
53
Del ejemplo HtmlWelcome aprendimos que, para generar una pgina Web, el servlet requiere de un estatuto out.println por lnea de cdigo HTML de la pgina Web. Para incluir el mensaje de confirmacin con el nombre del usuario, debemos construir un mensaje que incluya el nombre obtenido de la forma. De nuevo, sabemos cmo hacer esto usando la concatenacin de cadenas.
Antes de empezar a codificar, veamos si podemos aplicar la tcnica divide y conquistars a nuestra actividad de programacin. Necesitamos ver si podemos dividir nuestra tarea en secciones ms pequeas, cada una de las cuales ser probada individualmente para que est correcta antes de avanzar a la siguiente. Por una parte, parecen haber tres reas principales de debern ser manejadas por el servlet: Obtener de la forma la entrada del usuario, Procesar esta entrada si es necesario prepararla para generar una salida Preparar la salida en forma de una pgina Web.
Podemos codificar el servlet siguiendo estos tres pasos y despus intentar probarlo al final de cada paso para ver si lo que escribimos funciona correctamente. Sin embargo, no hay una mejor forma para probar los dos primeros, ya que el servlet no enviar ninguna respuesta al navegador al final de cada paso. Ya que la nica forma de confirmar que el servlet est trabajando correctamente es visualizar la pgina Web enviada como respuesta, resultara un buen primer paso construir una pgina Web que imite la especificacin de dicha pgina Web. Podremos entonces profundizar con las entradas actuales del usuario en los dos pasos posteriores. Planeemos entonces la escritura de nuestro cdigo en los siguientes pasos:
Escribe el cdigo para construir la pgina Web con un encabezado, un pie de pgina y un mensaje de confirmacin creado con algn nombre ficticio, usando la concatenacin de cadenas. Realiza una prueba abriendo la forma del archivo FormaPeticion.html en el workbench, enviando la forma y verificando que la pgina Web se despliegue correctamente. Escribe el cdigo para obtener la eleccin del usuario sobre la ciudad destino y construir una pgina Web con la imagen de la ciudad elegida. De nuevo, para hacer una prueba, abre la forma del archivo FormaPeticin.html utilizando el workbench, enva la forma y verifica que la pgina Web despliegue la imagen de la ciudad destino seleccionada. Escribe el cdigo para obtener el nombre del usuario y sustituirlo por el nombre ficticio en el mensaje de confirmacin. Igual que hiciste antes, prubalo abriendo la forma del archivo FormaPeticion.html en el workbench, enviando la forma y verificando que la pgina Web despliegue el nombre tal y como se introdujo en la forma.
A medida que codifiquemos los avances presentados anteriormente, toma en cuenta que cada paso implica lo siguiente:
Editar el archivo fuente del servlet PeticionViaje.java para incluir el cdigo de dicho paso. Compilar el archivo fuente del servlet utilizando el comando javac. Correr el servlet empleando la forma del archivo FormaPeticion.html y el Workbench.
54
Codificando el Servlet
En preparacin para escribir el cdigo de nuestro primer paso, emplearemos lo aprendido en los ejemplos HtmlWelcome y PersonalWelcome, aadiendo el siguiente cdigo:
Los estatutos out.println que generan la salida del mensaje de confirmacin que contengan el nombre ficticio Visitor. Escribiremos dos estatutos, uno que incluya una felicitacin dirigida al usuario por nombre y otro para la confirmacin de la peticin del usuario.
/** * Autor: Escribe tu nombre aqu * Fecha: Escribe la fecha aqu * Descripcin: Este servlet obtiene la entrada del usuario de la forma * FormaPeticion, y responde con una pgina * Web que tiene un mensaje de confirmacin con el nombre * del usuario y una imagen de la ciudad * destino. * */ import java.io.*; import javax.servlet.*; import javax.servlet.http.*; public class PeticionViaje extends HttpServlet { public void doPost( HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51
/** * Indica el tipo de contenido(por ejemplo, text/html), * que ser regresado en respuesta */ response.setContentType("text/html");
/** * Recupera un flujo de salida usado para enviar * datos al cliente */ PrintWriter out = response.getWriter();
/** * Obtiene de la forma la entrada del usuario * nombre y destino */ /* Aade aqu tu nombre */
/** * Inicia construyendo el encabezado de la pgina Web */ out.println( "<!DOCTYPE HTML PUBLIC '-//W3C//DTD HTML 4.01 Transitional//EN'>"); out.println("<HTML>"); out.println("<HEAD>"); out.println("<TITLE>Agencia Viajes de Informtica</TITLE>");
55
52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79
out.println("</HEAD>"); out.println("<BODY>");
/** * Aade el mensaje de confirmacin, con el nombre */ out.println("Hola Amigo!"); out.println( "Gracias por tu solicitud. Nos pondremos en contacto pronto.");
} // end-doPost }
Compila el servlet y ejectalo usando la forma del archivo FormaPeticion.html y el workbench. La siguiente captura de pantalla nos muestra un ejemplo de la respuesta del servlet:
56
En preparacin para escribir el cdigo para nuestro segundo paso, sabemos que el cdigo HTML para incluir un archivo de imagen en la pgina Web que ser regresada por el servlet deber ser similar al siguiente: <IMG src='/ny.jpg' alt='ny.jpg'> Observa que nuestra especificacin no nos dice cul debe ser el valor del atributo alt. Como sabemos que el cdigo HTML no sera vlido sin este valor, utilizaremos en nombre del archivo de la imagen que tenemos por ahora. Siguiendo los ejemplos HtmlWelcome y PersonalWelcome, tenemos:
El estatuto getParameter para obtener el valor del control de entrada de botn de radio llamado Destino Los estatutos out.println que generan la salida de cdigo HTML del servlet. Uno de estos estatutos incluye el cdigo HTML para la etiqueta IMG, cuyos atributos src y alt especifican, ambos, el archivo de imagen obtenido anteriormente.
/** * Autor: Escribe tu nombre aqu * Fecha: Escribe la fecha aqu * Descripcin: Este servlet obtiene la entrada del usuario de la forma * FormaPeticion, y responde con una pgina * Web que tiene un mensaje de confirmacin con el nombre * del usuario y una imagen de la ciudad * destino. * */ import java.io.*; import javax.servlet.*; import javax.servlet.http.*; public class PeticionViaje extends HttpServlet { public void doPost( HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
/** * Indica el tipo de contenido(por ejemplo, text/html), * que ser regresado en respuesta */ response.setContentType("text/html");
/** * Recupera un flujo de salida usado para enviar * datos al cliente */ PrintWriter out = response.getWriter();
/** * Obtiene la entrada del usuario de la forma : * nombre y destino */ String destination = request.getParameter("Destination");
57
42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81
/** * Comienza construyendo el encabezado de la pgina Web */ out.println( "<!DOCTYPE HTML PUBLIC '-//W3C//DTD HTML 4.01 Transitional//EN'>"); out.println("<HTML>"); out.println("<HEAD>"); out.println("<TITLE>iCarnegie Travel Agency</TITLE>"); out.println("</HEAD>"); out.println("<BODY>");
/** * Aade la imagen */ out.println("<IMG src='/" + destination + "' alt='" + destination + "'>");
/** * Aade el mensaje de confirmacin, con el nombre */ out.println("Hola Amigo"); out.println( "Thanks for your request. You will be contacted shortly.");
} // end-doPost }
Compila el servlet y ejectalo empleando la forma del archivo FormaPeticion.html y el workbench. Recuerda que debers cargar el archivo de clase del servelt PeticionViaje.class de nuevo en el workbench; de otro modo, el workbech utilizar el archivo de clase que se carg ah en el primer paso. La siguiente captura de pantalla muestra un ejemplo de la respuesta del servlet.
58
Preparndonos para escribir el cdigo para nuestro tercer paso, modifiquemos el cdigo como se indica a continuacin:
Aade el estatuto getParameter para obtener el valor del control de entrada de texto llamado Name Edita el estatuto out.println que genera la salida del saludo en el mensaje de confirmacin, para incluir el valor obtenido en el estatuto anterior en vez del nombre ficticio Amigo.
El Listado 4 muestra el cdigo de nuestro servlet una vez que hemos terminado de editarlo para este paso:
1 2 3 4 5 6 7 8 9 10 11 12 13 /** * Autor: Escribe tu nombre aqu * Fecha: Escribe la fecha aqu * Descripcin: Este servlet obtiene la entrada del usuario de la forma * FormaPeticion, y responde con una pgina * Web que tiene un mensaje de confirmacin con el nombre * del usuario y una imagen de la ciudad * destino. * */ import java.io.*; import javax.servlet.*; import javax.servlet.http.*;
59
14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74
public class PeticionViaje extends HttpServlet { public void doPost( HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
/** * Indica el tipo de contenido(por ejemplo, text/html), * que ser regresado en respuesta */ response.setContentType("text/html");
/** * Recupera un flujo de salida usado para enviar * datos al cliente */ PrintWriter out = response.getWriter();
/** * Obtiene la entrada del usuario de la forma : * nombre y destino */ String destination = request.getParameter("Destination"); String name = request.getParameter("Name");
/** * Comienza construyendo el encabezado de la pgina Web */ out.println( "<!DOCTYPE HTML PUBLIC '-//W3C//DTD HTML 4.01 Transitional//EN'>"); out.println("<HTML>"); out.println("<HEAD>"); out.println("<TITLE>iCarnegie Travel Agency</TITLE>"); out.println("</HEAD>"); out.println("<BODY>");
/** * Aade la imagen */ out.println("<IMG src='/" + destination + "' alt='" + destination + "'>");
/** * Aade el mensaje de confirmacin, con el nombre */ out.println("Hola, " + name + "!"); out.println( "Gracias por tu solicitud!. Nos pondremos en contacto pronto.");
/** *
60
75 76 77 78 79 80 81 82
*/ out.println("</BODY>"); out.println("</HTML>");
} // end-doPost }
Una vez ms, compila el servlet y correlo usando la forma en el archivo FormaPeticion.html y el workbench. Adems, recuerda cargar de nuevo el archivo de clase del servlet PeticionViaje.class al workbench, para evitar que el workbench utilice el archivo de clase del servlet cargado en el segundo paso. La siguiente captura de pantalla muestra un ejemplo de la respuesta del servlet..
61
62
El proceso de la programacin
Ya se han descrito los cuatro pasos para el desarrollo de pginas Web. Dichos pasos son: 1. Definir el contenido de la pgina Web 2. Planear la apariencia de la pgina y las ligas necesarias 3. Implementar la pgina Web, escribindola de forma incremental en pasos pequeos 4. Evaluar la pgina Web de dos formas: probndola para ver si el cdigo HTML es correcto y verificando que cumpla con la especificacin El proceso de desarrollo de paginas Web, es en esencia, el mismo proceso que los programadores utilizan para escribir un programa. Si se vuelve a leer Planeacin y desarrollo de un servlet, se podr deducir que, de hecho, aplicamos ah un proceso de creacin de paginas Web ligeramente modificado. Cada componente de este proceso modificado puede ser llamado una fase, en vez de un paso, donde cada fase puede hacer llamadas a una o ms iteraciones de los pasos principales que constituyen la fase. El proceso modificado aplicado a programacin, sera como se indica a continuacin:
Fase de Definicin Definir y/o redefinir el problema Fase de Planeacin Planear una solucin al problema Fase de Codificacin Codificar la solucin Fase de Evaluacin Evaluar y probar todo
El modelo general el proceso de desarrollo es en realidad circular en vez de lineal. A continuacin te presentamos una imagen del modelo:
Este proceso es aplicado por el programador para resolver un problema de programacin. Para iniciar el proceso de desarrollo, es necesario, definir el problema de la manera
63
correcta, esto implica que cuando se obtenga el requerimiento de solucin de un problema, replantear el problema con nuestras propias palabras, para de esta manera entenderlo y darle solucin al problema correcto, es importante asegurarse que se esta resolviendo el problema correcto, ya que es una practica comn en programacin el tratar de resolver un problema sin tener claro a lo que se quiere llegar, y encontrarnos en situaciones como la que se ilustra a continuacin
Si tu evaluacin indica que tu redefinicin o replanteamiento es correcto, debers comenzar a planear tu solucin (tu programa). Aqu es donde las habilidades de solucin de problemas entran en el proceso de programacin. La mayora de los programadores resuelven una parte muy pequea del problema original al principio y entonces resuelven la siguiente pieza pequea. Este proceso es llamado divide y vencers. Si divides el problema en pequeas partes, con frecuencia es posible reducir un gran problema en una serie de problemas ms pequeos y ms simples, cada uno de los cuales sern ms fciles de codificar en Java. Una vez que has decidido qu pieza del problema resolver, evala tu decisin y disea tu cdigo Java para el problema ms simple. Despus de escribir el cdigo, debers probarlo e inspeccionar los errores. Una vez que esta prueba demuestre que el cdigo funciona como debe, debers regresar al problema original con el cdigo de la pieza que resolviste funcionando y comenzar de nuevo el proceso. Esto puede sonar tedioso, pero si se aplica de una manera razonable, te ahorrar una gran cantidad de tiempo. Muchos programadores novatos (y tambin los expertos) obtienen un problema, van a la computadora y empiezan a codificar la solucin inmediatamente. Si bien ellos pueden pensar que esta es la forma ms rpida de terminar su trabajo, la experiencia a travs de los aos indica que mientras ms tiempo inviertas en realizar este proceso en papel, menos tiempo invertirs en el teclado. Programacin no es codificacin. Codificacin no es programacin. El proceso completo definido anteriormente es programacin. Si sigues el proceso, vers que invertirs, generalmente, unas pocas horas codificando en el teclado.
64
El API Java es una Interfaz de Programacin de Aplicaciones (API: por sus siglas en ingls) provista por los creadores del lenguaje Java, y que da a los programadores los medios para desarrollar aplicaciones Java. Como el lenguaje Java es un Lenguaje Orientado a Objetos, la API de Java provee de un conjunto de clases utilitarias para efectuar toda clase de tareas necesarias dentro de un programa. La API de java es tan basta que seria imposible tratar de memorizar todo sobre el lenguaje de programacin. Mucho depende de la prctica. Una habilidad crucial que puede acelerar el proceso de programacin es la habilidad para encontrar informacin rpida y correctamente al hacer referencia a la documentacin importante. Toda esta documentacin est disponible en el sitio Web de la Documentacin de API de Java, la direccin del API es la siguiente: http://java.sun.com/javase/6/docs/api/
La API Java est organizada en paquetes lgicos, donde cada paquete contiene un conjunto de clases relacionadas semnticamente. Un ejemplo de lo que se puede encontrar dentro de esta API es la clase java.io.PrintWriter, que ya se ha utilizado en programas anteriores, y que ayuda a devolver la pagina Web desde un servlet, la especificacin de esta clase, se encuentra en la siguiente direccin.
http://java.sun.com/javase/6/docs/api/java/io/PrintWriter.html
65
66
Otro aspecto en un buen estilo de programacin es escribir cdigo eficiente, adems que sea capaz de funcionar cmo es esperado de la forma ms ptima en trminos de tiempo y utilizacin de recursos del sistema. Una vez ms, este aspecto solo podr mejorarse con la experiencia y a travs del conocimiento del lenguaje de programacin.
Empezando con mayscula si se trata del nombre de una clase o interfaz, y empezando cada palabra en identificador con mayscula. CrculoColoreado Slo con maysculas si es el nombre de una constante. DIAS_HABILES
67
Empezando con minscula si es el nombre de cualquier otro identificador. De preferencia el nombre de cualquier mtodo debe ser un verbo en infinitivo y el de todo atributo un sustantivo. primerJugador, asignarSueldo().
Archivos fuente
Cada programa en Java es una coleccin de uno o ms archivos. El programa ejecutable se obtiene compilando estos archivos. En cada archivo especifica su contenido como sigue: 1. Los paquetes (instruccin package). 2. Los archivos de biblioteca (Instrucciones import). 3. Un comentario explicando el objetivo del archivo. 4. Las clases que defines en ese archivo.
Clases
Cada clase debe ir precedida por un comentario que explique su objetivo. Es recomendable especificar sus elementos como sigue: 1. Estructura de los objetos. Primero las variables y luego las constantes. 2. Elementos estticos. 3. Constructores. 4. Mtodos pblicos y privados. 5. Mtodos estticos. 6. Clases internas. Deja una lnea en blanco despus de cada mtodo. Todos los elementos deben estar precedidos por public, private o protected. Las variables deben ser privadas. Los mtodos y las constantes pueden ser privados o pblicos, segn se requiera.
Mtodos
Todo mtodo excepto main debe empezar con un comentario en formato javadoc El cuerpo de un mtodo no debe exceder 30 lneas de cdigo. Esto te obligar a dividir un mtodo complejo en varios ms sencillos.
Variables y Constantes
NO definas ms de una variable por lnea: int horas = 0, minutos = 0; //Mal es mejor: int horas = 0, minutos = 0;
68
No uses nmeros mgicos. Excepto -1, 0, 1 y 2 todas las literales numricas dentro del cdigo se consideran nmeros mgicos. if (p.horas() > 40) ... // MAL es mejor usar constantes definidas; final int HORAS = 40; .... if (p.horas() > HORAS) ...
//Bien
En proposiciones compuestas el parntesis que abre debe ir en la misma lnea que empieza tal proposicin. El parntesis que cierra debe estar slo en la ltima lnea de la proposicin y a la misma altura que la lnea de inicio:
while(hay_datos()) { proposiciones }
Usa lneas en blanco para separar partes de un mtodo que son lgicamente distintas.
Comentarios o documentacin
Con respecto a la documentacin se debe incluir lo siguiente: Un comentario al inicio de cada clase que contenga:
Descripcin del objetivo y restricciones de la clase. Descripcin de los datos de entrada que se requieren y de los que obtienen incluyendo el tipo de dato que se espera. Nombre del autor y fecha de realizacin (usando @author y @version).
/** Clases para ejemplificar los comentarios @author Pepe Pecas @version 1.00 31/11/2009 */ Al inicio de cada mtodo un comentario que indique el propsito, restricciones, paramentros y valor que devuelve el mtodo.
69
/** Dada una fecha especifica el da de la semana que fue. @param @return */ public int calculaPromedio( ) { ... } Si los atributos de una clase no son claros aclararlos con un comentario en su declaracin. Al inicio de cada mtodo hay que hacer un comentario indicando su propsito, y los mtodos que llama. Comentarios en el cuerpo de cada mtodo explicando caractersticas importantes o cierta lgica del mismo.
70
Cada objeto catfish tiene sus propios datos: row(fila), column(columna) , imageFileName(nombre del archivo de imagen).
Las operaciones de los datos son: getRow(), getColumn(), getImage(), swimRightIfPossible(), swimLeftIfPossible(), swimUpIfPossible(), swimDownIfPossible().
71
swimRightIfPossible. Incrementa el valor del atributo column, de ser posible. Cambia el valor del atributo imageFileName. swimUpIfPossible. Incrementa el valor del atributo row, de ser posible. Cambia el valor del atributo imageFileName.
En programacin, las conductas incluyen operaciones que consultan (query) tanto el estado como las operaciones que cambian el estado del objeto. A continuacin encontrars algunos ejemplos sobre las operaciones de un objeto pez que consultan sobre su estado:
Estas operaciones de consulta no son muy tiles en s para el objeto pez, sin embargo, son tiles para cualquier objeto que intente desplegar el pez. En otras palabras, el objeto pez provee estas operaciones de consulta como un servicio para los dems objetos. En terminologa de Programacin Orientada a Objetos, los servicios que un objeto puede proveer consisten en un conjunto de operaciones que puede llevar a cabo. Veremos ms adelante que un objeto puede restringir quin puede utilizar sus servicios.
Clases
Una clase de define como "un fragmento de software que define los datos (estado) y mtodos (conductas) de objetos concretos especficos, que son construidos posteriormente a partir de dicha clase" (The Java Language Environment, Sun Microsystems). Una clase es como una plantilla que modela todas las instancias de sus objetos. Todos los objetos tendrn todos los atributos y conductas definidos en la clase. Contrariamente, un objeto no puede tener ningn dato ni ejecutar ninguna operacin que no se encuentre en la definicin de su clase. Por ejemplo, nuestra sencilla clase Catfish no define una conducta "eat" (comer), por lo que ninguno de los objetos de tipo Catfish podrn ejecutar una operacin "comer". A continuacin se muestra la plantilla definida por nuestra clase Catfish:
72
La plantilla es utilizada para crear objetos. Cada objeto tiene su propio valor para cada atributo.
Accesibilidad: public (pblico) vs. private (privado) Como programadores, al disear una clase debemos considerar cuidadosamente las conductas y atributos que haremos accesibles para otros objetos. Si somos muy generosos al dar acceso, podrn ocurrir errores innecesarios. Ilustremos esto utilizando una analoga del mundo real. Cuando los diseadores de carros disean un auto, son cuidadosos sobre los controles que ponen disponibles para los conductores. El diseo de un carro espera que el conductor utilice el pedal de la gasolina, el pedal del freno y el volante. El diseo no espera que el conductor maneje manipulando vlvulas, velocidades y poleas debajo del cofre. Imagina los problemas (y dificultades) que podran ocurrir si el conductor pudiera manipular estos aspectos directamente. Aunque tales elementos existen y son parte esencial del automvil, pueden ser manipulados nicamente por otras partes del auto. Cuando diseamos clases, podemos pensar en que las cosas suceden de manera similar. Por diseo, existen aspectos privados (private) de una clase que, al igual que muchas de las partes internas de un auto, interactan nicamente con otras partes del carro. Adems, existen aspectos pblicos (public) de los objetos disponibles para sus usuarios para que interacten con l -- por ejemplo, el volante. Los objetos de otras clases pueden manipular solamente los atributos pblicos de los objetos y pueden utilizar nicamente los servicios pblicos de un objeto. Si te fijas en las clases de los objetos desde afuera, los nicos elementos que pueden ser vistos o manipulados son los pblicos. Llamamos interfase de una clase a la coleccin de sus aspectos pblicos. Java utiliza la palabra clave public para indicar tales elementos pblicos. Ocultamiento de informacin es un trmino que utilizamos para describir aquellas propiedades que no estn accesibles para el uso pblico. Java utiliza la palabra clave private para indicar dichas propiedades. Es importante notar que Java nos permite especificar no slo los datos de los elementos privados, pero tambin sus comportamientos. En OOP, un objeto usualmente mantiene privados sus atributos. Esto obliga a los dems objetos a enviar un mensaje solicitando un cambio de estado en vez de manipular directamente el estado. Por ejemplo, un auto tiene muchas ruedas y cinturones movibles. Si estuviramos modelando un auto, sera til capturar dichos comportamientos. Por ejemplo, nos ayudara a determinar cul de dos motores opera mejor el auto. Sin embargo, la nica conducta expuesta al usuario es el pedal de la gasolina. Al oprimir el pedal podra desencadenar mltiples conductas inaccesibles para el pblico, tales como cambiar la mezcla de oxgeno y combustible, dejar pasar ms combustible al motor, o cambiar las velocidades desde la
73
transmisin. Estas conductas, an cuando no son accesibles para el usuario de la clase, suceden detrs de escena. Podemos lograr esto en programacin haciendo privadas dichas conductas.
Atributos de Clase
La mayora de los atributos tienen valores especficos para el objeto. Por ejemplo, cada instancia catfish tiene sus propios valores de localizacin (por ejemplo, fila y columna). Algunos valores de atributos, sin embargo, son comunes para todas las instancias de una clase. Por ejemplo, supongamos que todos los peces deben gastar cierta cantidad de energa al nadar a una celda adyacente. Debido a que esta cantidad no depende del estado de ningn objeto, se considera entonces una propiedad de la clase como un todo. Llamaremos atributos de clase a dichas propiedades. Una propiedad de una clase no pertenece a un objeto de la clase en particular; pertenece a la clase. Podemos tener cien objetos tipo catfish, cada uno con sus valores de fila y columna. En contraste, independientemente del nmero de instancias de objetos catfish, necesitamos slo un valor en el programa para el atributo que representa la energa para nadar.
Constantes
74
El valor de un atributo cambia generalmente durante el tiempo de vida del objeto, pero existen algunos atributos para los cuales el valor no cambia una vez que es establecido. Por ejemplo, mientras la cantidad de combustible de un auto cambia durante el tiempo de vida de un carro, la capacidad mxima del tanque de gasolina no cambia una vez que se construye el carro. En otras palabras, el atributo de la "capacidad del tanque de gasolina" es una constante. As como un objeto puede tener atributos constantes, una clase tambin puede tener atributos constantes. Por ejemplo, el atributo de clase que representa la energa necesaria para nadar es en realidad una constante de la clase, debido a que la energa necesaria no debera cambiar una vez que el programa comienza a ejecutarse.
Para identificar los atributos de un objeto, busca adjetivos y frases posesivas tales como "X de Y" y "Y's X" en la especificacin del sistema. "nmero de cuenta" y "nombre del cliente" son ejemplo de los atributos de un objeto. Usualmente, los verbos no son atributos.
Para identificar las conductas, busca verbos. Por ejemplo, la frase "el cliente deposita dinero en la cuenta" indica la existencia de la conducta "depsito" Examina las dems partes del enunciado para determinar el remitente y el destinatario del mensaje. El sujeto del enunciado es "cliente". El sujeto inicia la accin y por lo tanto es el remitente del mensaje. El objeto es la entidad que recibe el mensaje. En nuestro enunciado hay dos objetos: "dinero", el objeto directo y "cuenta", el objeto indirecto. Para determinar quien recibe el mensaje, utilizaremos otro principio de OOP: Para cambiar el estado de un objeto, envale un mensaje en vez de cambiarlo directamente. Por lo tanto, preguntamos "Quin debe cambiar su estado a partir del mensaje?" En este caso, debera cambiarse el estado del objeto "Cuenta", por lo tanto, se convierte en el recipiente del mensaje. El otro objeto, "dinero", ser un parmetro del mensaje.
Al identificar conductas y atributos, unos pueden serlo y otros no. Para identificar las que no son obvias, inspecciona cada operacin y la lista con la secuencia de actividades que constituyen la operacin y los datos necesarios para realizar las actividades. Por ejemplo, mientras un carro est andando, la velocidad es muy importante. Tambin es importante la direccin del viaje. Ms an, dependiendo del tipo de programa que estamos escribiendo, tambin es importante conocer ms detalles, tales como la velocidad del motor, medido en RPMs (revoluciones por minuto). Por supuesto, no queremos pasar por alto un atributo muy importante -- la cantidad de combustible que tiene el auto. Al estudiar cuidadosamente qu hacen los objetos y qu necesitan para hacerlo, podemos determinar sus conductas, sus atributos obvios y los no obvios. Ilustraremos este proceso de diseo mediante el diseo de dos clases simples. Cuando entiendas bien este proceso, practcalo diseando tus propias clases para la aplicacin que presentamos a continuacin.
75
Descomponiendo el Problema El primer paso en el diseo de una solucin para este problema es preguntarnos, "Cules son los componentes de este sistema"? En este caso, tenemos tres componentes diferentes -- uno que podemos ver y dos que no podemos ver. La GUI es el componente que podemos ver y los que no, son los objetos BankAccount y AccountsLedger. Es muy importante darse cuenta que son objetos separados. La GUI controla todas las interacciones del usuario y contiene todo lo que podemos ver en la pantalla, incluyendo los campos de texto, los botones de radio y el botn de ejecucin. Generalmente no hace nada ms que administrar la interaccin con el usuario y la peticin de servicio de otros objetos. Una de las clases que se esconde detrs de escena, BankAccount, modela una cuenta de banco (llevando registro del balance, manejando los retiros y depsitos y dando el balance cuando es solicitado). Existe un objeto de este tipo para cada cuenta de banco. Otra clase detrs de escena, AccountsLedger, modela un libro mayor (manteniendo una coleccin de cuentas, creando y borrando cuentas cuando se solicita y buscando cuentas). Cuando discutamos el diseo de este applet, discutiremos sobre la clase AccountsLedger y la clase BankAccount por separado. Todo lo que necesitamos saber sobre el objeto GUI son dos aspectos: Que acta como un intermediario entre el usuario y nuestros objetos BankAccount y AccountsLedger y que utiliza los servicios del objeto BankAccount para retirar y depositar dinero y los servicios del objeto AccountsLedger para buscar cuentas especficas y para crear y borrar cuentas.
Diseando la Clase BankAccount Empecemos por discutir la clase BankAccount. Esta clase define el objeto esencial que modela la propia clase BankAccount (cuenta de banco). Un objeto BankAccount mantiene la cuenta de un cliente. La cuenta de un cliente incluye el nombre del cliente y el balance de su cuenta. A continuacin presentamos las clases para el diseo de dicha clase: 1. Identifica las conductas de las instancias de los objetos: La primera pregunta que debemos preguntarnos es "Qu servicios proveen las instancias de esta clase?". En otras palabras, cules son las conductas pblicas de las instancias de esta clase? Para cada operacin, tambin examinaremos la secuencia de actividades que el objeto debe desempear. Estas actividades nos revelarn la necesidad de conductas y atributos adicionales, algunos de los cuales sern pblicos y otros, privados. Inicialmente, probablemente vendrn a la mente conductas:
76
Deposit (Depsito). Depositar una cantidad de dinero especfica en la cuenta. La cantidad de dinero se especifica como un nmero entero. Entero implica que no se depositarn centavos de dlar, sin fracciones.
Secuencia de actividades necesarias para desempear esta operacin: Incrementa el balance de la cantidad especificada. Implicacin: Necesitamos almacenar balance como parte del estado del objeto.
Esta operacin debera ser parte de la interfaz pblica de BankAccount , ya que los objetos de otras clases deben ser capaces de enviar mensajes de depsito (deposit) a los objetos de tipo BankAccount. En el diseo actual, la operacin no genera una respuesta. En un diseo avanzado, los objetos de tipo BankAccount generan una respuesta indicando un error si la cantidad del depsito es un nmero negativo.
o
Withdrawal (Retiro). Retirar una cantidad de dinero especfica del balance o saldo de la cuenta. La cantidad de dinero se especifica como un nmero entero, donde el entero representa la cantidad de dlares.
Secuencia de actividades necesarias para realizar esta operacin: Decrementar el saldo de la cuenta a partir de la cantidad de dinero especificada. Implicacin: Necesitamos guardar el saldo de la cuenta (balance) como parte del estado del objeto.
Esta operacin tambin es parte de la interfaz pblica de BankAccount ya que los objetos de otras clases deben tener la capacidad de enviar mensajes de retiro (withdraw) a los objetos de tipo BankAccount. En el diseo actual, la operacin no genera una respuesta.
o
getBalance (inquiry) (obtenerBalance (consulta)). Regresa el saldo actual de la cuenta. El saldo es regresado como un entero. Esta conducta forma parte tambin de la interfaz pblica de BankAccount, ya que el objeto GUI debe tener la capacidad de enviar un mensaje de consulta (getBalance) a los objetos de tipo BankAccount, y en respuesta, obtener el saldo de la cuenta.
Las conductas presentadas anteriormente se derivan de las acciones que la GUI presenta al usuario. Pero, adicionalmente, existe otra conducta de esta clase: constructor. Sabemos que AccountsLedger necesitar crear una instancia de esta clase para modelar una cuenta de banco en particular. Adems, esta instancia de la clase deber ser inicializada. Esta es una generalidad de los objetos. Por lo tanto, aadiremos una conducta ms a nuestra lista:
o
Constructor. Crea e inicializa una cuenta para la persona cuyo nombre se especifica como una cadena de caracteres. Es necesario establecer el saldo inicial en ceros. El constructor tambin forma parte de la interfaz pblica ya que el objeto AccountsLedger deber ser capaz de crear nuevas cuentas de banco. Nota: Todas las clases tienen constructores de tipo pblico, con algunas excepciones. Una de las situaciones de excepcin se presenta cuando, por diseo, prohibimos que otras clases creen cualquier instancia de objetos. Esta discusin queda fuera del alcance de este curso.
77
Podemos abordar este tema con la siguiente pregunta: "Qu estado debern mantener las instancias de esta clase?". Tambin puedes plantearlo de esta forma: "Si el usuario de este objeto le pide que haga algo, qu necesita saber para hacerlo?" En el caso de la clase BankAccount, cada uno de los cuatro mtodos manipula el saldo o balance de la cuenta. El mtodo constructor la inicializa, withdraw y deposit lo modifican basndose en su valor anterior y getBalance regresa su valor actual. Con excepcin del mtodo constructor, el objeto necesita saber el valor anterior para comportarse adecuadamente. El mtodo BankAccount debe recordar tambin el nombre del propietario de la cuenta. Por lo tanto, tenemos dos atributos:
o
balance (saldo). la cantidad total de dinero de la cuenta, representada como un nmero entero de dlares. El valor de este atributo puede cambiar durante el tiempo de vida del objeto BankAccount y por lo tanto, no es una constante. Cada instancia del objeto tendr su propio valor para este atributo, por lo que decimos que es un atributo de instancia. Este atributo no forma parte de la interfaz pblica de la clase BankAccount ya que no queremos que los objetos de otra clase puedan modificar el saldo (balance) directamente. Al restringir el acceso a los mensajes withdraw y deposit, resulta ms fcil para el objeto BankAccount mantener la integridad de su estado.
name. el nombre de la cuenta, una cadena de caracteres. El valor de este atributo no puede cambiar durante el tiempo de vida de nuestro objeto BankAccount una vez que ha sido creado. Por lo tanto, es una constante. Cada instancia del objeto tendr su propio valor para este atributo, por lo que es un atributo de instancia y no un atributo de clase. Este atributo forma parte de la interfaz pblica de la clase BankAccount ya que no nos preocupa que objetos de otras clases puedan verlo directamente. Lo que sera preocupante es que otros objetos pudieran cambiar el valor del atributo name sin que nos enve un mensaje. Sin embargo, sabemos que otros objetos no podrn cambiar el atributo name , ya que lo hemos definido como constante.
3. Identificar los atributos de la clase BankAccount Si hemos decidido tener un saldo mnimo para las cuentas de banco, el "saldo mnimo" deber ser un atributo de clase, como discutimos en la seccin anterior "Atributos de Clases." Se trata de un atributo de clase, ya que su valor no depende del estado de ningn objeto. La poltica del banco aplica para todas sus cuentas. En este diseo, no hay saldo mnimo; por lo tanto, no contamos con este atributo. Si elegimos tener este atributo, bajo qu circunstancias lo convertiramos en una constante? Si no fuera una constante, lo declararas como un atributo pblico (public) o privado (private)?
78
Constructor. Crea una cuenta para la persona cuyo nombre est declarado como una cadena de caracteres e inicializa el saldo en $0. deposit. Incrementar el saldo de la cuenta, a partir de la cantidad de dinero especificado. La cantidad de dinero se especifica como un entero que representa los dlares que sern depositados. Esta conducta no regresa nada. withdraw. Decrementa el saldo de la cuenta, a partir de la cantidad de dinero especificada. La cantidad de dinero se especifica como un entero que representa los dlares que sern retirados. Esta conducta no regresa nada. getBalance (inquiry). Regresa el saldo actual de la cuenta, como un entero.
Atributos:
balance. la cantidad total de dinero en la cuenta, como un entero. Este atributo no es una constante. Es un atributo de instancia (lo opuesto a un atributo de clase). Este atributo es privado. name. el nombre del cliente, como una cadena de caracteres. Este atributo es una constante, ya que el nombre no cambia una vez que ha sido definido. Es un atributo de instancia. Este atributo es pblico.
Ejemplo de un Proceso de Diseo: AccountsLedger Un objeto AccountsLedger mantiene una coleccin de cuentas de banco. Diseando la Clase AccountsLedger Hagamos un anlisis similar para identificar las conductas y los atributos: 1. Identificar las conductas de las instancias de objetos: Al igual que hicimos antes, debemos preguntarnos lo siguiente: "Qu servicios provee este objeto?" Inicialmente, nos vendrn a la mente tres conductas:
o
Create BankAccount (crear cuenta de banco). Crea un nuevo objeto BankAccount para un cliente cuyo nombre se especifica como una cadena de caracteres. Esta conducta es parte de la interfaz pblica, ya que la GUI puede enviar mensajes de este tipo.
Secuencia de actividades para ejecutar esta operacin: Agregar el objeto BankAccount recientemente creado a la coleccin de cuentas de banco. No es necesario regresar nada como respuesta a este mensaje. Implicacin: Requerimos una coleccin de objetos BankAccount como atributo. Llamaremos accounts (cuentas) a este atributo.
79
Delete BankAccount (borrar cuenta de banco). Elimina una cuenta de banco de un cliente. El nombre del cliente se especifica como una cadena de caracteres. Es parte de la interfaz pblica, ya que la GUI puede enviar mensajes de este tipo.
Secuencia de actividades: Primero, busca un objeto de tipo BankAccount cuyo nombre es igual a la cadena de caracteres especificada. Si lo encuentra, remueve dicho objeto de la coleccin accounts. No es necesario regresar nada como respuesta a este mensaje. Implicacin: Requerimos un mtodo que haga una bsqueda por nombre en una cuenta de banco. Nota: en esta aplicacin, podemos borrar una cuenta an cuando su saldo no sea cero.
Lookup BankAccount (buscar cuenta de banco). Encuentra el objeto BankAccount que pertenece a un cliente. El nombre del cliente es especificado como una cadena de caracteres. Es parte de la interfaz pblica, ya que la GUI puede enviar mensajes de este tipo.
Secuencia de actividades: Inspecciona cada cuenta de banco y revisa si el nombre de la cuenta corresponde al nombre del cliente. Si hay correspondencia, regresa la cuenta. La conducta regresa un objeto de tipo BankAccount.
Secuencia de actividades: El atributo accounts debe estar inicializado como una coleccin vaca.
2. Identificar los atributos de instancia: El objeto AccountsLedger debe mantener una coleccin de objetos BankAccount que pueda manipular.
o
3. Identificar los atributos de clase de AccountsLedger: Ningn atributo aplica a la clase AccountsLedger como un todo
Create (crear). Crea un nuevo objeto BankAccount para un cliente. El nombre debe ser una cadena de caracteres. No es necesario que este mensaje regrese una respuesta. Es parte de la interfaz pblica. Delete (borrar). Borra la cuenta de banco de un cliente. El nombre del cliente deber ser especificado como una cadena de caracteres. No es necesario de que mensaje regrese una respuesta. Es parte de la interfaz pblica.
80
Lookup (buscar). Busca en una cuenta de banco, por el nombre del cliente. El nombre del cliente debe ser una cadena de caracteres. Regresa el objeto BankAccount que corresponda, si encuentra alguno. Es parte de la interfaz pblica. Constructor. Cuando se crea un nuevo objeto AccountsLedger, la propiedad accounts deber ser inicializada como una coleccin vaca.
Atributos:
accounts (cuentas). Una coleccin de cuentas de banco (BankAccount) que se encuentran en el libro mayor. Para que un objeto de tipo AccountsLedger pueda mantener su estado de consistencia, necesitamos que otros objetos no puedan cambiar el valor de este objeto sin enviarnos un mensaje. Por lo tanto, este atributo no es parte de la interfaz pblica.
Aqu terminamos la especificacin de las clases BankAccount y AccountsLedger. Ahora, debemos cambiar esta especificacin a lenguaje Java. Antes de hacerlo, debers practicar el proceso de diseo.
La habilidad para identificar las propiedades y las conductas La habilidad para identificar los criterios de accesibilidad apropiados (privados o pblicos) La habilidad para distinguir entre atributos de objeto y atributos de clase La habilidad para identificar constantes
A continuacin, presentamos el applet de un directorio telefnico. El directorio telefnico puede utilizarse para almacenar y buscar informacin de contactos. Al presionar el botn "add | modify" (aadir | modificar), si ya existe en el directorio un registro con el nombre especificado, se modifica la informacin del contacto. Si no existe dicho contacto, se agrega al directorio telefnico un contacto con el nombre y telfono especificados. Observa que el nmero telefnico puede incluir caracteres no numricos tambin. Obsrvalo, experimenta con l y familiarzate con la forma en que trabaja.
Este sistema est compuesto por tres clases -- una que podemos ver y dos que no. La GUI es la clase que podemos ver y las que no, son las clases PhoneBook y Contact. La clase PhoneBook tiene una lista de contactos, mientras que la clase Contact contiene un par con el nombre y el telfono. Realiza una especificacin en lenguaje natural (espaol) para las clases PhoneBook y Contact. No te preocupes por la GUI. Tu especificacin para cada una de las tres clases debe ser independiente de las dems y debe describir tanto las conductas y los atributos de las instancias de objetos y los atributos de clase. Debers seguir un formato lo ms similar posible al que utilizamos en el ejemplo. Como apoyo, a continuacin te recordamos el tipo de preguntas que debers hacerte durante este proceso. Recuerda, debers escribir ambas especificaciones por separado, cada una
81
deber contener las tres categoras y finalmente, haz una lista y describe cada elemento de cada categora. Conductas de las instancias de objeto: La primera pregunta que debemos hacernos es "Qu tipo de servicios deben proveer los objetos de esta clase? En este caso, podemos preguntar "Qu le pedir el usuario a esta clase"? Haz un listado de la secuencia de actividades necesarias para ejecutar cada conducta. La secuencia de actividades puede revelar conductas adicionales y atributos que no haban sido obvios. No olvides el constructor. Atributos de las instancias de objeto: Las preguntas a realizar son: "Qu atributos constituyen el estado del objeto?" y "Que atributos de instancia descubriste al examinar las conductas?" Atributos de clase: Puedes abordar este punto con la pregunta: "Existe algn valor de un atributo que aplique para toda la clase?" En otras palabras, "es suficiente tener solo un valor para la clase, independientemente del nmero de instancias de objetos?" Tiene sentido tener este valor, an cuando no hay instancias?" Para cada conducta, recuerda responder lo siguiente
La conducta debe ser parte de la interfaz pblica, como se discuti en la seccin Accesibilidad: pblico vs. privado? En otras palabras, pueden los objetos de otras clases enviar directamente mensajes de este tipo? Para procesar este mensaje, qu debe especificarse como parte de los mensajes de este tipo? Qu debe regresar el "remitente" de este mensaje? Qu secuencia de actividades ser requiere para completar esta operacin?
Es el atributo una constante, tal y como se discuti en la seccin Constantes? En otras palabras, cambia su valor una vez que ste es establecido? Puede el atributo puede ser parte de la interfaz pblica, tal y como se discuti en la seccin Accesibilidad: pblico vs. privado? En otras palabras, pueden los objetos de otras clases cambiar directamente el valor de este atributo, sin enviarle un mensaje a este objeto? Puede esperarse que este objeto mantenga su valor constante todo el tiempo?
82