viernes, 6 de mayo de 2011

Demostración Final

Taller de Programación Orientada a Objetos

Demostracion Final.



VIDEO DEMOSTRACION:

Interfaces Gráficas

Programación Orientada a Objetos - Semana 13 - Reporte 12


Interfaces Gráficas en JAVA



Las GUI (Graphic User Interface) o Interfaz Gráfica de Usuario es una forma de hacer los dispositivos más accesibles a los usuarios en general.
Las interfaces gráficas son en realidad un componente o programa que corre en segundo plano en el sistema donde se ha implementado, su función es transformar cada una de las instrucciones, métodos, acciones o comandos en componentes visuales (haciendo uso de imagenes, pequeños iconos, efectos y demás).
Todo esto convierte un entorno de línea de comandos en un entorno visual más atractivo e intuitivo al usuario lo que es una invitación a utilizar nuestro sistema o aplicación

La necesidad de las interfaces gráficas surge como una consecuencia de la falta de conocimientos por parte de los usuarios sobre el manejo y uso de las CLI (Interfaces de Línea de Comandos) había la necesidad de masificar los sistemas, pero aprender cientos de instrucciones, sintaxis, parámetros y demás no era una buena solución.



Las Interfaces gráficas automatizan gran parte de este trabajo, ya que no es necesario aprender toda una instrucción textual, solo es necesario aprender la funcionalidad de un botón para lograr los resultados deseados.

Los sistemas operativos implementan diferentes gestores GUI o entornos de escritorio, solo por mencionar algunos:

  • Windows XP: LUNA
  • Windows Vista/Seven: AERO
  • MAC OS: AQUA
  • Linux: GNOME, UNITY, KCD

Java ofrece una serie de librerias que facilitan en gran medida la implementación interfaces gráficas.


java.awt(Abstract Windowing Toolkit)


Es el paquete original de herramientas GUI de Java. Las principales ventajas AWT son que viene incluída en todos los paquetes de tecnología Java, incluyendo implementaciones de Java en navegadores de Internet y es muy estable.

AWT es un conjunto de herramientas muy simples con pocos componentes GUI, administradores de diseño, y eventos.
Esto se debe a Sun Microsystems decidió utilizar un mínimo común denominador (LCD) para el enfoque de AWT.
Como resultado de ello, y por desgracia, algunos de los componentes de uso común, tales como tablas, árboles, barras de progreso, y otros, no son compatibles. Para las aplicaciones que necesitan más tipos de componentes, es necesario crearlas desde cero. Esta es una gran carga.

AWT ofrece tres tipos de componentes principales:


a) Básicos: Componentes básicos en cualquier GUI.

  • Button
  • CheckBox
  • Container
  • Panel
  • Window
  • Frame
  • Label
  • List
  • TextComponent
  • MenuComponent


b) Layouts: Sirven para acomodar los componentes de la GUI.

  • FlowLayout
  • GridLayout
  • BorderLayout
  • CardLayout
  • GridBagLayout


c) Eventos: Otorgan funcionalidades a cada uno de los componentes de la GUI.

  • KeyEvent
  • ActionEvent
  • MouseEvent
  • TextEvent



javax.swing


El paquete Swing es parte de la JFC (Java Foundation Classes) en la plataforma Java. La JFC provee facilidades para ayudar a la gente a construir GUIs.

Las componentes Swing se identifican porque pertenecen al paquete javax.swing.

Swing existe desde la JDK 1.1 (como un agregado). Antes de la existencia de Swing, las interfaces gráficas con el usuario se realizaban a través de AWT (Abstract Window Toolkit), de quien Swing hereda todo el manejo de eventos. Usualmente, para toda componente AWT existe una componente Swing que la reemplaza, por ejemplo, la clase Button de AWT es reemplazada por la clase JButton de Swing (el nombre de todas las componentes Swing comienza con "J").

Las componentes de Swing utilizan la infraestructura de AWT, incluyendo el modelo de eventos AWT, el cual rige cómo una componente reacciona a eventos tales como, eventos de teclado, mouse, etc... Es por esto, que la mayoría de los programas Swing necesitan importar dos paquetes AWT: java.awt.* y java.awt.event.*.

Ojo: Como regla, los programas no deben usar componenetes pesados de AWT junto a componentes Swing, ya que los componentes de AWT son siempre pintados sobre los de Swing. (Por componentes pesadas de AWT se entiende Menu, ScrollPane y todas las componentes que heredan de las clases Canvas y Panel de AWT)

Swing abarca componentes como botones, tablas, marcos, paneles, ventanas, etc...





APLICACIÓN AL PROYECTO


Es clave en mi proyecto desarrollar una interfaz gráfica amigable para el usuario. Mi intención es desarrollar algo parecido a la factura en físico, con un orden parecido.

En general, la ventana siempre estará compuesta por 2 paneles. El panel de barra de menú y el panel del área de trabajo




El panel de menú tendrá diferentes opciones las cuales se activaran dependiendo del área de trabajo. Para ello implementaré un JMenuBar. Si alguien por ahí sabe como implementarlo pues no dude en comentar.

El área de trabajo sera dinámica, ya que es la que cambiará con cada opción que se elija. Para ello se deberán utilizar de manera creativa los Layouts disponibles en java.awt.
Algunos paneles que me serán útiles son GridLayout, BorderLayout, FlowLayout y el dios GridBagLayout :).
Otros componentes necesarios para mi proyecto serán los básicos: JLabel, JButton, JTextField, JTextArea; asi como implementar de forma correcta el JTable


SALUDOS!! :)

REFERENCIAS




Implementación de Interfaces Gráficas

Taller de Programación Orientada a Objetos - Semana 13 - Reporte 12.

Mi intención es colocar algo parecido a esto, tomando en cuenta el diseño personalizado que el cliente ha pedido.




Para lograr mi objetivo, decidi implementar el VIEW CONTROLLER MODEL.
En este caso solamente mi sistema extiende a un JFrame, mi clase Sistema es como el gestor de la GUI, se encarga de recibir los paneles de otros métodos y de mostrarlos en la pantalla:




Para tener una mejor estructura en mi código y no sobrecargar las clases, decidí distribuir la tarea de crear paneles. Asi por ejemplo, la factura es un panel formado por 4 paneles individuales, que a su vez se componen de paneles independientes armados por cada subclase. Como es el caso del segundo panel contenedor de la factura, el cual recibe los paneles de origen y destino de los métodos correspondientes de cada subclase:




Cuando se entra a la primera pantalla, se implementa un JMenuBar, con varias opciones disponibles, se invita al usuario a elegir una de ellas. Aquí parte del código de la implementación del JMenuBar:




Posterior a eso, se redibuja la pantalla y dependiendo de la opción seleccionada es el panel que se mostrará:



- Si se elige Facturacion > Nueva Factura se mostrará esta pantalla.



La pantalla de nueva factura mostrará todo el entorno de edición de una factura, un tipo de formulario donde se podrán introducir todos los datos necesarios.
Lo botones del final son las acciones que se pueden realizar con la factura.
  • Imprimir: Para imprimir la factura en papel. Conexión con una impresora.
  • Exportar: Para exportar la factura. A XML o PDF.
  • Guardar: Guarda la factura en la base de datos.
  • Limpiar: Limpia todos los campos.


- Si se elige Facturacion > Buscar se mostrará esta pantalla.



Se introducen las palabras clave y al presionar el botón buscar se envían las palabras clave como parámetros a la función buscarFactura(), la cual a su vez conecta con la base de datos por medio de un proxy, el proxy regresa los resultados y buscarFactura los procesa para mostrarlos dentro de un JTable().

Otra cosa que no se debe olvidar son los ActionListener, de que le sirve a uno tener interfaz gráfica, si no tenemos ActionListeners. Estos componentes nos ayudan a asignar acciones a cada botón, movimiento del ratón, etc. Aqui les muestro parte del código de alguno de mis ActionListeners:



La interfaz que he diseñado la hice utilizando muchos tipos de Layouts, definitivamente el que más me ayudo fue el GridBagLayout el cual es realmente poderoso.

SALUDOS :)


Referencias

Presentacion Final

Programación Orientada a Objetos - Semana 14 - Reporte 13

Presentación Final



SALUDOS :)

jueves, 5 de mayo de 2011

Implementacion de Sistemas Distribuidos

Taller de Programación Orientada a Objetos - Semana 12 - Reporte 11

Para mi proyecto, decidí programar un Sistema Distribuido por medio de sockets (TCP).

Su funcionamiento es simple. El sistema lo probé en forma local y funciona a base de 5 clases:

- SocketServer: Es la clase que se encarga de las tareas del servidor, su función es la de generar un Proxy entre el servidor y la base de datos principal. Después espera a recibir las peticiones, una vez recibidas se encarga de procesarlas y posteriormente enviar las palabras clave al Proxy para realizar la búsqueda dentro de la base de datos. Si se encuentran coincidencias en la base de datos, el Proxy almacena los resultados en un ArrayList y regresa la lista al servidor, el servidor empaquetara los resultados y enviara la ArrayList al cliente. Limpia la memoria y cierra conexiones.

- SocketCliente: Se encarga de realizar las peticiones. Se pide el nombre de la empresa y el RFC de la misma, dichos parámetros se envían al servidor empaquetados en un String. Se espera la respuesta del servidor, la cual es recibida en forma de ArrayList. Una vez recibida la respuesta, se desempaqueta por medio de un Iterador (Iterator) y después se siguen desempaquetando los resultados individuales por medio de un StringTokenizer(). El Iterador a la vez va imprimiendo los resultados uno a uno. Limpia memoria y cierra conexiones.

- Origen implements Serializable: Esta clase es muy sencilla, es donde se almacenan el nombre y RFC del cliente. Esta clase es Serializable. Sus atributos son el nombre y RFC ambos en forma de string, su unico metodo es toString() que empaqueta el objeto en un String para ser enviado.

- Resultados extends ArrayList implements Serializable: Es la clase usada por SocketServer para empaquetar los resultados de la búsqueda, no se si fue la forma mas optima de hacerlo pero funciono a la primera :). Una lista de Strings que es serializable para poder ser enviada.
Los resultados almacenan datos como el folio de la factura, la empresa destino y su ubicación, el total a pagar de la factura y la fecha en la cual la factura fue capturada.
Por ahora solo estoy trabajando con una base MySQL con facturas ficticias.

- Proxy: Conecta la base de datos con la aplicación principal (solo SocketServer) proporciona los métodos necesarios para interconectar la base de datos MySQL, realizar búsquedas, borrar registros, actualizar registros, crear registros, etcétera.

La aplicación funciono satisfactoriamente, no esperaba tan buenos resultados, les dejo las capturas de pantalla donde se ve la ejecución de la misma.

Pantalla SocketServer



Pantalla SocketClient



Les dejo el código al final de la entrada. No incluyo la clase Proxy por lo que no podran compilarlo y correrlo, pero sé que les servirá de referencia.

SALUDOS :)

domingo, 1 de mayo de 2011

Sistemas Distribuídos

Programación Orientada a Objetos - Semana 12 - Reporte 11

SISTEMAS DISTRIBUIDOS

Un sistema distribuido se define como: una colección de computadoras separadas físicamente y conectadas entre sí por una red de comunicaciones distribuida; cada máquina posee sus componentes de hardware y software que el usuario percibe como un solo sistema (no necesita saber qué cosas están en qué máquinas).

El usuario accede a los recursos remotos (RPC) de la misma manera en que accede a recursos locales, o un grupo de computadores que usan un software para conseguir un objetivo en común.

Los sistemas distribuidos deben ser muy confiables, ya que si un componente del sistema se descompone otro componente debe de ser capaz de reemplazarlo, esto se denomina Tolerancia a Fallos.

El tamaño de un sistema distribuido puede ser muy variado, ya sean decenas de hosts (red de área local), centenas de hosts (red de área metropolitana), y miles o millones de hosts (Internet); esto se denomina escalabilidad.

En Java se puede utilizar la Invocación Remota de Métodos o RMI para establecer un sistema distribuido.

El sistema de Invocación Remota de Métodos (RMI [Remote Method Invocation] ) de Java permite a un objeto que se está ejecutando en una Máquina Virtual Java (VM) llamar a métodos de otro objeto que está en otra VM diferente compartiendo así recursos y carga de procesamiento a través de varios sistemas.

Existen tres procesos que participan en una aplicación RMI:
  1. Cliente (Client): Es el proceso que invoca los métodos de los objetos remotos.
  2. Servidor (Server): Es el proceso que crea los objetos, hace referencia a los mismos y espera a que sean invocados por el cliente.
  3. Registro de Objetos (Object Registry): Crea las referencias a los objetos en el servidor. Los objetos son registrados con éste proceso y una vez que son registrados se puede obtener acceso al mismo con tan solo su nombre.
Las aplicaciones distribuidas deben cumplir 3 tareas específicas para funcionar:
  1. Localizar objetos remotos. Las aplicaciones pueden utilizar diversos mecanismos para obtener referencias a objetos remotos. Por ejemplo, una aplicación puede registrar sus objetos remotos con el registro RMI. Por otra parte, una aplicación puede pasar y devolver referencias de objetos remotos como parte de otras invocaciones remotas.
  2. Comunicarse con objetos remotos. Los detalles de la comunicación entre objetos remotos son manejados por el RMI. Para el programador, la comunicación a distancia es similar a regular llamadas a métodos Java.
  3. Cargar las definiciones de clases para los objetos que se pasan a través de la aplicación. Debido a que RMI permite a los objetos pasar en dos direcciones (Ida y Vuelta), se proporciona mecanismos para cargar las definiciones de clase de un objeto, así como para la transmisión de datos de un objeto.
La siguiente ilustración muestra una aplicación RMI distribuida que utiliza el registroRMI para obtener una referencia a un objeto remoto. El servidor llama al registro paraasociar (o unen) un nombre con un objeto remoto. El cliente busca el objeto remotopor su nombre en el registro del servidor y luego invoca un método en él. La ilustración también muestra que el sistema RMI utiliza un servidor Web existentepara cargar las definiciones de clase, del servidor al cliente y del cliente al servidor,para los objetos cuando sea necesario.


Realizar un sistema distribuido con RMI es algo sencillo, se pueden seguir los siguientes pasos:


1. Crear un servidor RMI

  • Definir un objeto remoto que va a ser utilizado por los clientes. Para crear un objeto remoto...
  • Definir una interfaz, y el objeto remoto será una clase que implemente dicha interfaz.
2. Definir el interfaz remoto
  • El interfaz debe ser público.
  • Debe extender (heredar de) el interfaz java.rmi.Remote, para indicar que puede llamarse desde cualquier máquina virtual Java.
  • Cada método remoto debe lanzar la excepción java.rmi.RemoteException en su claúsula throws, además de las excepciones que pueda manejar.

APLICACIÓN AL PROYECTO

En el caso de mi proyecto, mi idea es aplicar algo equivalente al servicio que ofrecen las tiendas de conveniencia en línea.

Seria un portal, ya sea en línea o por medio de una aplicación java móvil que permite descargar la factura en formato PDF a la computadora o dispositivo móvil.
Por ahora y por el poco tiempo restante, solo me encargaría de hacer el sistema en línea.

Como método de autentificación se pediría el RFC del cliente (esté a su vez se convertiría en un filtro para solo mostrar las facturas almacenadas en la base de datos que correspondan a ese cliente)

Después, si lo sabe el cliente, se pediría el folio de la factura a descargar. Si el cliente no sabe el folio de la factura se procede a imprimir una lista de las facturas correspondientes al cliente para que pueda verificar y descargar la que desee.

Una vez seleccionada la factura, el programa, en silencio, recupera la factura y arma un PDF que puede ser descargado.


REFERENCIAS

jueves, 14 de abril de 2011

Implementación de Pruebas Unitarias

Taller de Programación Orientada a Objetos - Semana 11 - Reporte 10

Como mencione la clase anterior mencione para qué funciona el JUnit, lo descargamos y configuramos; ahora voy a utilizarlo para realizar algunas pruebas unitarias en mi código:

1. La clase en la que se implementarán las pruebas unitarias de llama Converter.java.
Los métodos a probar son los siguientes:

Existen dos métodos getStringOfNumber(), la diferencia es que uno recibe un flotante y el otro un entero. Ambos serán probados en el test.

Diseño de la Prueba

Primero importaremos las librerias de nuestro Test JUnit y marcaremos nuestro Test como parte del paquete principal:

Despues programamos el Test.

Estos son los métodos del Test. testUno() se encarga de verificar si efectivamente el valor en letra del entero escrito en la variable String expected es igual a la String result cuyo valor es el que la función getStringOfNumber() esta retornando.

testDos() hace exactamente lo mismo pero con un double.

Incluímos tambien la funcion main() que es la que inicializa el test.

Los resultados fueron variados, mi primer resultado fue utilizando el test assertTrue(), este metodo afirma si una condición es verdadera. Como atributo utilicé la función a.equals(b), la cual compara dos strings y regresa 1 o 0 como valor. Entonces assertTrue recibe dicho valor y si es 1 se pasa el test, si es 0 el test tiene un error.

El testUno() no se paso porque la cadena no es igual. Yo especifique lo siguiente:

137 = CIENTO TREINTA Y SIETE

pero para el test:

137 = CIENTO TREINTA Y SIETE PESOS 0/100 MN.

porque getStringOfNumber() me regresa el valor en letra pero en tipo moneda.

Entonces solo hace falta modificar la variable String expected de testUno() y realizamos la prueba otra vez

Ahora ambos test fuerons pasados.



Saludos :)

miércoles, 13 de abril de 2011

Diseño de Pruebas Unitarias

Programación Orientada a Objetos - Semana 11 - Reporte 10

Mientras desarrollamos una aplicación atravesamos varias fases, pero no hay fase de desarrollo más importante que la fase de pruebas.
Con las pruebas comprobamos que nuestro código realmente haga lo que esperamos y especificamos, y que cumpla con los requerimientos establecidos al inicio.

Las Pruebas Unitarias (Unit Test), se consideran las más importantes para garantizar un proyecto exitoso. Dichas pruebas se encargan de probar clases aisladamente y están relacionadas con el código y responsabilidad de cada clase y sus fragmentos de código más críticos.

Por ejemplo: una clase que sume dos números, y devuelva el resultado. La prueba se encargara de probar el método y verificando que efectivamente sume dos números correctamente y devuelva el resultado correcto.

Ventajas de las Pruebas Unitarias

  • Asegura calidad del código entregado.
  • Es la mejor forma de detectar errores tempranamente en el desarrollo. No obstante, esto no asegura detectar todos los errores, por tanto prueba de integración y aceptación siguen siendo necesarias.
  • Ayuda a definir los requerimientos y responsabilidades de cada método en cada clase probada.
  • Permite encontrar errores o bugs tempranamente en el desarrollo.

Entre muchas otras ventajas, como probar la eficiencia de nuestro código ante el estrés (tiempos de espera y de ejecución).

Proceso

Los pasos para crear pruebas unitarias exitosas son los siguientes:

  • Antes de implementar una determinada funcionalidad, piensa cómo deberías probarla para verificar que se comporta correctamente. Esto permite desarrollar la funcionalidad teniendo las ideas muy claras de lo que debería hacer.
  • Escribe el código que implementa la funcionalidad deseada.
  • Escribe el código de las pruebas inmediatamente después.
  • Ejecuta las pruebas que hiciste.
  • Corrige la unidad de código que implementa la funcionalidad deseada hasta que pase todas y cada una de las pruebas.
  • Al añadir una nueva funcionalidad, repite el ciclo: piensa en cómo probarla, codifica la funcionalidad, codifica las pruebas, ejecuta todas las pruebas que hiciste (nuevas y viejas). No sigas hasta que el código pase absolutamente todas las pruebas.
  • Así una y otra vez para cada nueva funcionalidad que implementes.

JUNIT
JUNIT es un conjunto de clases (framework) que permite realizar la ejecución de clases Java de manera controlada, para poder evaluar si el funcionamiento de cada uno de los métodos de la clase se comporta como se espera. Es decir, en función de algún valor de entrada se evalúa el valor de retorno esperado; si la clase cumple con la especificación, entonces JUnit devolverá que el método de la clase pasó exitosamente la prueba; en caso de que el valor esperado sea diferente al que regresó el método durante la ejecución, JUnit devolverá un fallo en el método correspondiente.

Para realizar su trabajo, JUNIT utilizama métodos ASSERT. Un método Assert es un método de JUnit que realiza una prueba y que retorna un “AssertionFailedError” si la prueba fallo. Para más información sobre dichos métodos visitar las referencias al pie de la entrada.

Configurar JUNIT

1. Descargar el Framework de JUNIT (Descarga directa: [junit4.9b2.zip])
2. Extraer el contenido del paquete.
3. Colocar la carpeta en junit4.9b2 alguna ubicación conocida. (en mi caso /home/juancarlos/)
4. El paso anterior es para configurar el CLASSPATH. Abrimos una terminal, nos aseguramos que estamos en nuestra carpeta personal (en mi caso /home/juancarlos, en su caso /home/sunombredeusuario) y escribimos emacs -nw .bashrc



5. Nos vamos hasta el final del archivo y escribimos la siguiente linea:



Todo es en una sola línea, no poner ningún salto de línea. En el CLASSPATH van escritas las direcciones de las librerias contenidas en 3 archivos .jar. Las tres direcciones van separadas por el caractér de dos puntos ( : ) mas o menos con la siguiente sintaxis:

export CLASSPATH=/UBICACION/junit4.9b2/junit-4.9b2.jar:/UBICACION/junit4.9b2/junit-4.9b2-src.jar:/UBICACION/junit4.9b2/junit-dep-4.9b2.jar:.

Listo, con ello ya hemos ubicado nuestras librerias, ahora podemos comenzar a escribir y compilar pruebas con JUNIT.

IDENTIFICACIÓN DE PRUEBAS

Despues de llenar la factura, se necesita calcular el total a cobrar. Dicho total debe ir escrito en número y letra.
Para obtener el total en número basta con realizar todas las operaciones (suma, resta, multiplicación, división) correctamente. Pero, para obtener el número con letra, el valor debe enviarse a una función y después de procesarlo se debe enviar el valor con letra. Por ejemplo:

1. Se captura una orden, el total a cobrar de dicha orden es de 1535.50
2. El atributo total almacena el valor: orden.total = 1535.50
3. Se genera un nuevo Conversor (clase) y el total de envía a la función llamada getStringOfNumber(float num). getStringOfNumber(orden.total)
4. El método getStringOfNumber regresa una cadena de caracteres (String) que contiene el valor del total en letra.
5. Se espera que getStringOfNumber regrese MIL QUINIENTOS TREINTA Y CINCO PESOS 50/100 M.N

De la misma manera, implementando polimorfismo, hay un método getStringOfNumber() que en lugar de recibir un flotante, recibe un entero.
La finalidad es la misma solo que se trabaja con números de tipo INT (Integer)

REFERENCIAS Y TUTORIALES

martes, 12 de abril de 2011

Implementación de Eventos, Excepcion y Errores propios

Taller de Programación Orientada a Objetos - Semana 10 - Semana 9

Aquí les muestro algunas capturas de pantalla implementando eventos y excepciones.

EVENTOS
Todos mis eventos están orientados a la interfaz gráfica, es por ello que les muestro como quedarían algunos de mis eventos implementando una de las barras de herramientas.

Implementación en el Código





Ejecución



EXCEPCIONES

1. Comenzamos por analizar los menús; cuando entramos a un menú en pantalla, hay que elegir una opción válida. Las opciones válidas son números dentro del rango permitido (el rango esta dado por el número total de opciones). Si se elige una opción fuera de ese rango ocurrirá una excepción y se imprimirá un mensaje en pantalla. De igual forma, si se introduce un carácter, espacio, salto de línea, tabulación, etcétera; como opción, se mostrará un mensaje de error también.

Implementación en el Código



Ejecución


2. Después de que elegimos una opción, hay que cargar los datos de la empresa. Los datos de la empresa están almacenados en un archivo de sistema el cual hay que leer.
Aquí puede ocurrir otra excepción, cuando el archivo no es encontrado. Si eso pasa, se muestra un mensaje de excepción y no se puede realizar ninguna factura.

Impementación en el Código







Ejecución

3. Cuando se toman los datos del concepto a facturar, hay campos en los que forzozamente hay que introducir un valor númerico, tal es el caso del precio y la cantidad de artículos de un solo tipo. En este caso se implementa un NumberFormatException.
Si ocurre la excepción, es decir, se introdujo como valor un caractér, un espacio, tabulacion o salto de línea, cualquier cosa menos un número; se mostrará un mensaje de excepción y se pedirá el valor de nuevo.

Implementación en el Código
Ejecución

Espero les sirva la información de esta entrada.

Suerte :)

miércoles, 6 de abril de 2011

Identificación de Eventos, Excepciones y Errores propios

Programación Orientada a Objetos - Semana 10 - Reporte 9

Cuando diseñamos una aplicación todos estamos expuestos a los errores y las excepciones. De la misma forma, generamos eventos que nos sirven para realizar diversas acciones dentro de nuestro programa.

EVENTOS


Los eventos, como ya mencioné, son acciones que el usuario inicia y que el programa procesa regresando un resultado, lo que se conoce como respuesta (por lo general, aunque no siempre).
En java, la clase padre de todo tipo de eventos es la clase java.awt.Event

Algunos tipos de eventos son:

- KeyEvent: se produce cuando el usuario presiona alguna tecla.
- MouseEvent: cuando el usuario mueve el mouse o presiona alguno de los botones del mismo.
- WindowEvent: son eventos relacionados con las ventanas de la aplicación, ejemplos pueden ser abrir la ventana o cerrarla.
- ActionEvent: son eventos variados, acciones que se realizan sobre los componentes de la aplicación, por ejemplo el presionar un botón.
- TextEvent: relacionados al texto, se producen por ejemplo al cambiar el texto que ingresamos.

Java captura los eventos utilizando interfaces de escucha o Listeners. Para cada tipo de evento hay una interfaz de escucha:

- MouseEvent , MouseListener
- ActionEvent , ActionListener.


EXCEPCIONES


Las excepciones son situaciones eventuales que pueden presentarse dentro del tiempo de ejecución de nuestro programa, por lo general, una excepción la podemos identificar antes de tiempo y así programar la manera en la que nuestro programa deberá capturarla y gestionarla. Tras capturar la excepción, es posible, si así se desea, continuar desde el punto donde se produjo la excepción.

Las hay de dos tipos:

- RuntimeException: errores en el tiempo de ejecución. Son causadas por los programadores, por ejemplo, si se divide entre cero o se intenta acceder mas allá de la memoria reservada para un arreglo.

- IOException: errores de entrada y salida. Por ejemplo, intentar accesar o modificar archivos inexistentes, o sin el permiso requerido.

Cuando se produce un error, se genera un objeto Throwable. Los objetos Throwable contienen un mensaje (String) que almacena una descripción del error; la pila de memoria (stack) existente al momento de generar el objeto y la causa, tambien de tipo Throwable con la que podemos presentar el error en sí.

Las excepciones se capturan mediante los bloques try - catch. Cada sentencia try debe ir seguida de una sentencia catch, y cada método o clase puede indicar el tipo de objeto Throwable a lanzar. Por ejemplo:

public void function () throws IOException {
...
// código libre de excepciones
...
try {
...
// código que posiblemente lance una excepción
...
} catch (IOException error) {
...
// qué hacer en caso de excepción
...
}
}

ERRORES


Los errores por lo general, van más allá de nuestro alcance. Son situaciones criticas que no podemos manejar de forma habitual, incluso, no deberíamos intentar capturarlas y gestionarlas. Indican otro tipo de fallos de los cuales no podemos recuperarnos y solo queda finalizar la ejecución del programa.

Los errores más tipicos hacen referencia a fallos del sistema:

- Memoria agotada.
- Accesar a espacios ya reservados, por otros programas, en la memoria.
- Sobrecarga del procesador.
- Perdida de la conexión a base de datos, internet.
- Problemas de hardware.

Por lo general este tipo de errores deben visualizarse antes que todo, es decir, verificar las capacidades del sistema al cual orientamos nuestro programa, evitar errores en la lógica de la aplicación que causen ciclos o procesos infinitos que sobrecarguen el sistema, etcétera.

Errores y excepciones detienen la ejecución normal de nuestro código, los errores son los únicos que pueden forzarnos a cerrar nuestra aplicación, en cambio, las excepciones, nos permiten continuar la ejecución normal de nuestro código sabiendo manejar dichas excepciones de forma correcta.

IDENTIFICACIÓN DE EVENTOS, ERRORES Y EXCEPCIONES EN MI PROYECTO.

Eventos propios.

La gran mayoría de mis eventos estarán enfocados a la interfaz gráfica, más que nada al tipo ActionEvent ya que colocare una gran cantidad de botones en algo que emulará una barra de herramientas.

Además incluiré varios eventos de tipo TextEvent, estos eventos notificarán a mi aplicación cuando los datos de una factura que vaya ingresando sean modificados.


Excepciones.

Muchas excepciones han sido previstas por mi código. Comenzando por las básicas que son las de entrada y salida.
Dentro de los menús principal y secundarios: ¿Estás eligiendo una opción válida?. De no ser así, se produce una excepción con un mensaje y se vuelve a dar la oportunidad de elegir la opción válida.



Dentro del módulo de facturación, lo primero que se hace es cargar los datos de la empresa (proveedor, supplier), guardados en un archivo: ¿Existe el archivo? ¿Es el correcto?. Si no es así, la excepción permite llenar un segundo archivo correcto y es el que se procede a cargar. El primer archivo, de estar ahí, se convierte en basura y el segundo se convierte en el archivo correcto.



En el módulo de facturación, al crear nueva factura hay que pedir los datos: ¿Es el tipo de dato correcto? Esto más que nada se produce al pedir cantidades numéricas, por ejemplo precios o cantidad de artículos. Te pido un Integer o Double, pero me das un carácter; la excepción muestra un mensaje y te permite dar otro valor.




En la base de datos. ¿Se pudo abrir la base de datos? ¿Se pudo guardar el dato? ¿Se pudo accesar a los datos?. La excepción mostrara un mensaje según corresponda.

Errores

Hasta ahora no tengo ningún error previsto, pero algunos de ellos pueden ser:

En la lista de artículos de la factura, la lista es tan grande que te haz quedado sin memoria.
La interfaz gráfica es muy pesada o elaborada, algunos sistemas no pueden cargarla ocasionando la finalización del programa.
El iterador, al leer los nodos de la lista siguió un ciclo infinito y sobrecarga el procesador.
Hemos usado comandos de sistema y el código no es portable, ocasionando errores de compatibilidad.
Librerías que no están presentes ocasionando errores de ejecución y el mal funcionamiento de ciertas partes del código.


Referencias

miércoles, 30 de marzo de 2011

Aplicación de Patrones de Diseño

Talle de Programación Orientada a Objetos - Semana 9 - Reporte 8

BUILDER PATTERN (Constructor)

Las partes de mi código que encajan con las especificaciones del patrón Builder son:


- Constructor: Mi clase Billing proporciona la interfaz y funciones para generar la factura.
- Constructor Concreto: En éste caso se trata del constructor de la Factura, el cual ensambla las partes individuales.
- Director: .
- Parte: Las partes son el Proveedor, Origen, Destino y Orden.
- Producto: El producto es la Factura.

En mi caso el primer paso es generar la factura al pedir los datos. Mi constructor sera Billing y su método makeNewBill() para construir la factura

Posterior se envían los objetos individuales al constructor de la clase Bill() :


Y el producto final es una Factura la cual se imprime en pantalla:


A partir de este producto es posible generar varios productos distintos, pues es posible imprimir la Factura, exportarla a otro formato como PDF, o generar la factura electrónica.


COMPOSITE PATTERN (Compuesto)

El Patrón compuesto lo aplique al momento de pedir los datos de cada objeto individual, cada campo que es necesario para generar ya sea el Origen, Destino ú Orden; son hojas del objeto indiviual; y cada objeto individual (pero compuesto) se vuelve hoja de lo que es la Factura principal.


Se envían los objetos a la factura y después la factura se puede guardar en la base de datos.

En éste caso el patrón compuesto se combina con el patrón constructor para generarla factura.

ITERATOR (Iterador)

Por último, en el proyecto solo he aplicado un iterador, en esté caso la función del iterador es la de ingresar a la orden del cliente para imprimir en pantalla los conceptos a facturar.


Falta implementar algunos iteradores más, porque necesito tener la capacidad de modificar los datos de la orden o agregar nuevos datos.

La implementación de los patrones fue algo complicada, de hecho siento que "emule" a los patrones y no los aplique concretamente ya que en cierto momento mi código no compiló y trate de tener algo sólido para presentar.

SALUDOS