miércoles, 24 de noviembre de 2010
jueves, 21 de octubre de 2010
Model View Controler
es imprescindible definir los papeles que van a desempeñar cada elemento de nuestra aplicación.
Una manera metódica de conseguir esto es usar el patrón de diseño Model View Controler.
Este patrón que se refleja en el siguiente esquema nos permite separar el código , la visualizacion y el acceso a datos.
Como se puede apreciar en la vista se consigue eliminar cualquier vestigio de código java nativo, apoyandose en las distintas herramientas que nos ofrece java.
El controlador se encarga de realizar las llamadas con los datos obtenidos de la vista y cargar el modelo que se va a utilizar (una lista de productos, un nombre,..)
Este modelo es cargado por la vista oportuna (se indica en el mismo controlador con redirecciones por ejemplo) que usando dichos datos solo debe concentrarse en mostrarlos en el formato deseado al usuario.
domingo, 17 de octubre de 2010
Filter
El uso de filtros es otra de las herramientas en el desarrollo de componentes web.
Ejemplos prácticos de su uso serían los que siguen.
Control de acceso: evitar el acceso a partes de nuestra aplicación/sitio si el usuario no está registrado.
Insertar fragmento de HTML (una cabecera o un pié ) a todas las páginas de nuestro sitio.
Evitar el “robo” de imágenes de una página a un usuario no registrado.
El planteamiento sería similar al de CSS (Cascading Style Sheet) o las hojas de estilo, en el que definimos aparte una apariencia que se aplica a todo nuestro sitio, agilizando los cambios y manteniendo el código ligero. Es preferible definir las directivas de acceso en un único lugar a tener que realizar las comprobaciones en todo el código.
El filter, como el servlet y el listener está ligado al archivo web.xml, por lo que este es un punto de partida a la hora de localizar un comportamiento no deseado por nuestro filtro (o servlet o listener).
public class FiltroAcceso implements Filter {
Ejemplo de control de acceso
NOTA:
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
Como se puede observar el tipo de request, del filtro es de tipo ServletRequest en vez de HttpServletRequest, por lo que si queremos poder acceder a los datos contenidos en los distintos ámbitos del request es necesario hacer modelado con el request para que se asemeje al que usamos en los servlets eso se hace como sigue:
HttpServletRequest httprequest=(HttpServletRequest)request;
HttpSession session=(HttpSession)httprequest.getSession();
publicvoiddoFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
HttpServletRequest httprequest=(HttpServletRequest)request;
HttpSession session=(HttpSession)httprequest.getSession();
Object atributo=session.getAttribute("usuario");
Usuario usuario=(Usuario) atributo;
if(usuario!=null)
chain.doFilter(request, response);
else{
request.getRequestDispatcher("./index.jsp?mensaje=Login para acceder a ese apartado").forward(request, response);}
}
El texto marcado en verde es el que gestiona la peticion, antes de dicho texto podemos hacer las operaciones que deseemos. En el ejemplo si hay un usuario logado atendemos su peticion, en caso contrario lo redirigimos a una pagina en concreto.
<filter>
<display-name>FiltroAcceso</display-name>
<filter-name>FiltroAcceso</filter-name>
<filter-class>filter.FiltroAcceso</filter-class>
</filter>
<filter-mapping>
<filter-name>FiltroAcceso</filter-name>
<servlet-name>ControladorBorradoProducto</servlet-name>
</filter-mapping>
<filter-mapping>
<filter-name>FiltroAcceso</filter-name>
<servlet-name>ControladorCarrito</servlet-name>
</filter-mapping>
Entre las etiquetas <filter> se define el filtro en las secciones. Las direccitas <filter-mapping> definen a que partes de nuestra aplicación se palica el filtro.
Listener
Un listener tiene distintos ambitos de aplicación. El asistente de eclipse nos ofrece los siguientes:
Distinguimos nuevamente tres tipos de ambitos, son los mismos que se vieron en servlets pero con diferente nombre:
ServletContext: Ambito de aplicación
HTTPSession: Ambito de sesión
ServletRequest: Ambito de petición
Así por ejemplo para conectar a una base de datos creariamos un listener de servletcontext, que se conectara al inicio de una peticion y se desconectará al terminar esta.
En el fichero web.xml un listener tendría el siguiente aspecto:
< listener >
<listener-class>listener.GestionConexionMysql</listener-class>
</ listener >
La clase java que implementa un listener tendria el siguiente aspecto:
publicclassListenerRequestimplementsServletRequestListener {
publicvoidrequestDestroyed(ServletRequestEvent arg0) {}
//Codigo a ejecutar antes de atender la peticion
publicvoidrequestInitialized(ServletRequestEvent arg0) {
//Codigo a ejecutar tras atender la peticion
}}
Es a través del implements como especificamos el ambito de la peticion.
Notese que se implementan requestDestroyed y requestInitialized
Servlet
El servlet es una de las partes mas importates en el desarrollo de componentes web con Java,
si bien la gestión de la presentación de datos hace que el uso de JSP sea más cómodo y recomendable.
El servlet al crearse se incluye en el archivo de definición web.xml, de igual forma se puede definir el servlet manualmente sin hacer uso del asistente de elcipse.
La definición de un servlet en el xml es la siguiente:
<servlet>
<description></description>
<display-name>Nombre mostrado</display-name>
<servlet-name>Nombre del servlet</servlet-name>
<servlet-class>Clase java</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>Nombre mostrado en URL</servlet-name>
<url-pattern>/Ruta al recurso</url-pattern>
</servlet-mapping>
<servlet>
En cuanto a la clase java, su apariencia es la que sigue:
publicclassSERVLETextendsHttpServlet {
privatestaticfinallongserialVersionUID= 1L;
protectedvoiddoGet(HttpServletRequest request,HttpServletResponse response)throwsServletException, IOException {
}
protectedvoiddoPost(HttpServletRequest request,
HttpServletResponse response)throwsServletException, IOException {
}}
En los métodos doGet y doPost el servlet realiza su función.
Un error común es no redireccionar estos métodos.
Así si escribimos el código en el doGet(). El método doPost debe tener una llamada al anterior
doPost(HttpServletRequest request,HttpServletResponse response)
throwsServletException, IOException {
doGet(request,response);}
Está indicación es recomendable en ambos sentidos así, si usamos el doPost el doGet debe redirigir la petición al doGet.
La response del servlet da acceso a los siguientes objetos:
PrintWriter writer=response.getWriter();
writer.print("CODIGO HTML "+Valor de variable u objeto,...);
A través de request, se puede acceder a los siguientes campos:
request.getParameter("nombreVariable")
request.getSession.getAtribute("nombreObjeto");
request.getSession.getAtribute("nombreObjeto");
request.getSession().getServletContext ().getAtribute("nombreObjeto");
Las líneas anteriores definen los ambitos, estos pueden ser:
Request: petición, está "muere" al ser pintada.
Session: Sesión del usuario, para un usuario en concreto.
ServletContext: De aplicación, vive mientras esta se ejecute.
En las peticiones con getAttribute("VAR"), el objeto recuperado precisa del correspondiente casting que defina a que clase en particular pretece el objeto.
Al igual que recuperamos datos de distintos ambitos con getAtribute(""), también podemos almacenarlos haciendo uso de setParameter("NombreVariable",objeto) o setAtribute("NombreVariable",objeto)
El setParameter o getParameter solo tiene sentido en el contexto (scope) de la peticion (request).
Un método interesante del request es el siguiente:
request.getRequestDispatcher("./URL").forward(request,response);
Dado que la impresión/ generación de las vistas con SERVLET no es cómoda, normalmente el uso de servlet opera en la siguiente capa a las vistas (JSP) gestionando las redirecciones y las peticiones del usuario o sitio.
Desarrollo de componentes web con Java
Servlets
Filters
Listeners
JSP
Se detallarán las consideraciones de estos componentes en posteriores entradas, incidiendo en aspectos a tener en cuenta a la hora del desarrollo.
Los SERVLETs están fuertemente ligados al archivo web.xml de una aplicación web. Principalmente su función es una vez obtenidas las peticiones de la vista, dirigir dicha petición a la vista correspondiente, al servicio que procesa esos datos, ..
El JSP se centra en el campo de la representación de datos, para lo que hacemos uso de Expression Language y las etiquetas personalizadas. Son de uso habitual aquí el HTML y el CSS.
Los LISTENERs inicializan datos como puede ser una conexión a la base de datos o crear un elemento en el ambito de la aplicación.
Los FILTERs proporcionan una capa adicional en la seguridad y el control de las peticiones. Por ejemplo limitando el acceso a determinadas secciones si el usuario no está registrado.
Programación orientada a Evento POE
Mientras la programación orientada a objeto se centra en la estructura de los objetos, este enfonque de la programación se centra en sus relaciones.
El que un objeto “actue”, se cree u otra operación desencadena una serie de procesos, eventos, en los demas objetos.
Debemos considerar el evento como una situación que desencadena otra.
En la imagen se pueden apreciar los elementos que participan en este tipo de programación.
Launcher es el que genera un evento.
Dispatcher indica quien debe recibir el evento
Listener recibe u oye el evento y actúa cuando se produce.
En base a su relación podemos indicar lo siguiente:
Un launcher puede tener muchos eventos.
Un evento tiene un unico Launcher.
Un evento puede ser escuchado por muchos listeners.
Un Dispatcher solo tiene un launcher.
Un launcher puede tener muchos dispatchers.
Un listener puede atender a muchos dispatcher.
Un dispatcher puede repartir a muchos listeners.
En el campo del desarrollo de componentes web podemos encontrar en los listeners.
El siguiente es un ejemplo claro del diagrama anterior en el que se facilita la identificación de los actores.
Imaginemos la bolsa.
Tenemos una pizarra de valores (Es nuestro lanzador de eventos),
en el parque tenemos a los brokers (son los dispatchers), fuera tenemos a los clientes.
Así cuando un broker recibe un evento, por ejemplo la subida de una empresa en concreto, este transmite el evento a sus clientes como se muestra en el siguiente diagrama.
Este paradigma de programación, es de mucha utilidad en el diseño de interfaces gráficas de usuario (GUI) si bien en el desarrollo de componentes web su aplicación es limitada.
Enlaces:
domingo, 26 de septiembre de 2010
Processing
Processing nos proporciona una manera rápida y sencilla de generar salida gráfica a nuestros programas. Para usarlo basta importar las correspondientes librerias (Ver enlace).
En nuestra clase definimos dos métodos que extienden PApplet.
public void setUp(){
// Aqui preconfiguramos la salida, inicializamos objetos,..
}
public void draw(){
// Este metodo es el encargado de dibujar la salida, por lo que se ejecuta continuamente.
}
Mas información:
http://processing.org/learning/
http://processing.org/download/
http://processing.org/learning/basics/
Reflection
Reflexión (reflection) es un framework habitualmente poco conocido. Este framework nos permite preguntar al código por si mismo.
Aunque su uso no sea muy conocido, a nivel interno componentes como Hibernate lo usan.
Un ejemplo más cercano es la programación de servlets dentro de una pagina web dinámica.
En el fichero web.xml, podemos indicar a reflection como “generar la clase”.
Un ejemplo de lo anterior es el siguiente:
<servlet>
<servlet-name> Nombre </servlet-name>
<servlet-class> Nombre fichero java</servlet-class>
<servlet>
<servlet-mapping>
<servlet-name> Nombre </servlet-name>
<servlet-pattern> Nombre fichero java</servlet-pattern>
<servlet-mapping>
Reflecttion se encuentra dentro de java.lang.Object con lo que todos los objetos pueden hacer uso de él.
Reflection nos proporciona los siguientes métodos:
public String getName()
public Class getType()
public Object get(Object obj)
public void set (Object obj, Object value)
public Class[] getParameterTypes()
public Cass getReturnType()
Si bien mediante estos métodos reflexión solo obtiene los campos y métodos públicos de una clase. A través de los métodos constructores, getters y setters podríamos obtener información suficiente para reconstruir la clase o bien interactuar con ella con la suficiente seguridad de la corrección.
Más información:
http://download.oracle.com/javase/tutorial/javabeans/introspection/index.html
http://download.oracle.com/javase/tutorial/reflect/index.html
Programación orientada a objeto
paradigma.
( Del lat. Paradigma, y este del gr. παράδειγμα).
1. m. Ejemplo o ejemplar.
2. m. Ling. Cada uno de los esquemas formales en que se organizan las palabras nominales y verbales para sus respectivas flexiones.
3. m. Ling. Conjunto cuyos elementos pueden aparecer alternativamente en algún contexto especificado; p. ej., niño, hombre, perro, pueden figurar en El -- se queja.
L a programación orientada a objetos o POO es un paradigma de programación que usa objetos y sus interacciones, para diseñar aplicaciones y programas informáticos . Está basado en varias técnicas, incluyendo herencia , abstracción, polimorfismo y encapsulamiento . Su uso se popularizó a principios de la década de los años 1990.
La programación orientada a objetos es una forma de programar que trata de encontrar una solución a estos problemas. Introduce nuevos conceptos, que superan y amplían conceptos antiguos ya conocidos. Entre ellos destacan los siguientes:
Clase : definiciones de las propiedades y comportamiento de un tipo de objeto concreto. La instanciación es la lectura de estas definiciones y la creación de un objeto a partir de ellas.
Herencia : por ejemplo, herencia de la clase C a la clase D) Es la facilidad mediante la cual la clase D hereda en ella cada uno de los atributos y operaciones de C, como si esos atributos y operaciones hubiesen sido definidos por la misma D. Por lo tanto, puede usar los mismos métodos y variables publicas declaradas en C. Los componentes registrados como "privados" (private) también se heredan, pero como no pertenecen a la clase, se mantienen escondidos al programador y sólo pueden ser accedidos a través de otros métodos públicos. Esto es así para mantener hegemónico el ideal de OOP.
Objeto : entidad provista de un conjunto de propiedades o atributos (datos) y de comportamiento o funcionalidad (métodos) los mismos que consecuentemente reaccionan a eventos. Se corresponde con los objetos reales del mundo que nos rodea, o a objetos internos del sistema (del programa). Es una instancia a una clase.
Método : Algoritmo asociado a un objeto (o a una clase de objetos), cuya ejecución se desencadena tras la recepción de un "mensaje". Desde el punto de vista del comportamiento, es lo que el objeto puede hacer. Un método puede producir un cambio en las propiedades del objeto, o la generación de un "evento" con un nuevo mensaje para otro objeto del sistema.
Evento: Es un suceso en el sistema (tal como una interacción del usuario con la máquina, o un mensaje enviado por un objeto). El sistema maneja el evento enviando el mensaje adecuado al objeto pertinente. También se puede definir como evento, a la reacción que puede desencadenar un objeto, es decir la acción que genera.
Mensaje: una comunicación dirigida a un objeto, que le ordena que ejecute uno de sus métodos con ciertos parámetros asociados al evento que lo generó.
Propiedad o atributo: contenedor de un tipo de datos asociados a un objeto (o a una clase de objetos), que hace los datos visibles desde fuera del objeto y esto se define como sus características predeterminadas, y cuyo valor puede ser alterado por la ejecución de algún método.
Estado interno: es una variable que se declara privada, que puede ser únicamente accedida y alterada por un método del objeto, y que se utiliza para indicar distintas situaciones posibles para el objeto (o clase de objetos). No es visible al programador que maneja una instancia de la clase.
Componentes de un objeto: atributos, identidad, relaciones y métodos.
Identificación de un objeto: un objeto se representa por medio de una tabla o entidad que esté compuesta por sus atributos y funciones correspondientes.
En comparación con un lenguaje imperativo, una "variable", no es más que un contenedor interno del atributo del objeto o de un estado interno, así como la "función" es un procedimiento interno del método del objeto.
martes, 7 de septiembre de 2010
TestNg aclaración
Ejericio
|
|SRC|---principal
|
|
|TEST|-principal
Las clases pruebas se haran dentro de la carpeta Test y el paquete principal. Esta manera de organizar los archivos permite desde la carpeta de pruebas acceder a las clases principales sin necesidad de import y demás consideraciones de la privacidad
Pruebas de caja blanca

Mientras que en la entrada anterior nos centrábamos en los parámetros de entrada y salida de una clase y lo que nos devolvía, en este tipo de pruebas lo que nos va a interesar es como se relacionan entre si las clases.
Las pruebas de caja blanca o caja transparente son más exigentes que las de caja negra, ya que se concentran en la forma en que el programa realiza su funcionalidad para lograr el resultado, y no en el resultado en sí.
Haremos uso de la librería Mockito
Mockito nos permite crear "objetos simulados", que interactuen con nuestro objeto, sin necesitar de implementarlos.
Se siguen los siguientes pasos:
1.Definir el objeto a probar.
2.Definir la relación entre el objeto simulado (mock) y nuestra clase.
3.Invocación
4.Comprobación de resultados y comportamientos
Siguiendo el ejemplo anterior de la venta de entradas, tenemos la clase Cine que debe comunicarse con el servicioAsignacionButaca,
la clase servicioAsignacionButaca carece de implementación, solo conocemos en cine los métodos de dicha clase que vamos a necesitar.
1.Definir el objeto a probar.
Cine cine=new Cine()
ServicioButaca servicioButacaMock=mock(ServicioButaca.class);
2.Relación entre objetos
cine.servicioButaca=servicioButacaMock
3.Invocación.
cine.reservaEntrada(Pelicula,Fecha)
//reservaEntrada(..) hace uso del metodo reservaButaca de la clase "mockeada";
4.Comprobación de resultados
verify(ServicioButacaMock).reservaButaca(pelicula,fecha)
El uso de mocks no sólo permite verificar la comunicación. Tenemos opciones adicionales para el control de excepciones o los valores de retorno de una función.
when(....).return(VALOR)
VERIFY(....).nombreMetodo
WHEN(...).thenThrow(EXCEPCION)
Pruebas de caja negra
Las pruebas de caja negra, no tienen en cuenta el funcionamiento interno del programa, sino unicamente el resultado de las comunicaciones entre objetos. Dichas interacciones se verifican mediante el uso de asserts.
Un assert es una condición que se debe dar en un programa para que no se produzca un error.
Esta metodología de diseño garantiza que una clase en particular se comporte de una forma en particular.
Mediante esta metodología y a través del uso del desarrollo dirigido por pruebas, podemos garantizar ese comportamiento en concreto. Para realizar las pruebas hacemos uso de la librería TestNg
En esta metodología seguimos el siguiente proceso:
1 Elegir un requerimiento
2 Escribir una prueba:
3 Verificar que la prueba falla:
4 Escribir la implementación: Escribir el código más sencillo que haga que la prueba funcione. Se usa la metáfora "Déjelo simple" ("Keep It Simple, Stupid" (KISS)).
5 Ejecutar las pruebas automatizadas:
6 Eliminación de duplicación: eliminar código repetido.
7 Actualización de la lista de requerimientos:
A modo de ejemplo:
Tenemos la siguiente clase, public class Taquilla{...};
La taquilla tiene el método Entrada:ventaEntrada(Pelicula,Fecha)
Sean los comportamientos deseados:
- Si la Pelicula no se proyecta lanza excepcion RuntimeException("La pelicula no se emite")
- Si la Fecha es anterior a hoy lanza excepcion RuntimeException("Fecha incorrecta")
- Si la película se emite y la fecha es correcta devuelve una entrada.
El proceso de diseño de la prueba sigue los siguientes pasos:
1.Nombre de la prueba.
public class VentaEntradasTest
2. Nombre del método
@Test
public void ventaEntradas()
3.Definir el objeto a probar.
Taquilla taquilla=new Taquilla();
4. Escenario de la prueba
Cine cine=new Cine();
Date hoy=new Date(YYYY,MM,DD)
/*El cine debe contener películas
Es necesario en este paso compilar, ver lo que falla, comunicar métodos.
Inicializar el escenario
*/
5.INVOCACION
entrada=ventaEntrada(Pelicula,fecha);
6.COMPROBACIÓN RESULTADOS Y MENSAJES ERROR
Con el uso de assert podemos verificar los resultados y dar los mensajes de error correspondientes.
En esta fase se escribe el minimo código necesario para que la prueba pase.
boolean enCartelera=cine.cenCartelera(Pelicula)
assert(enCartelera):”La película no se emite”;
boolean fechaOk=hoy.before(Fecha);
assert(fechaOk):”La fecha es anterior a hoy”;
miércoles, 28 de julio de 2010
Programación Ágil: extreme programming
Las metodologías ágiles de software surgen como respuesta a la gestión rígida, que impone la programación heroica (convencional). Dentro de estas metodologías ágiles, encontramos XP, o extreme programming.
Por definición lo deseable en XP es lo siguiente:
Características fundamentales
Las características fundamentales del método son:
Desarrollo iterativo e incremental: pequeñas mejoras, unas tras otras.
Pruebas unitarias continuas, frecuentemente repetidas y automatizadas, incluyendo pruebas de regresión. Se aconseja escribir el código de la prueba antes de la codificación. Véase, por ejemplo, las herramientas de prueba JUnit orientada a Java, DUnit orientada a Delphi y NUnit para la plataforma.NET. Estas dos últimas inspiradas en JUnit.
Programación en parejas: se recomienda que las tareas de desarrollo se lleven a cabo por dos personas en un mismo puesto. Se supone que la mayor calidad del código escrito de esta manera -el código es revisado y discutido mientras se escribe- es más importante que la posible pérdida de productividad inmediata.
Frecuente integración del equipo de programación con el cliente o usuario. Se recomienda que un representante del cliente trabaje junto al equipo de desarrollo.
Corrección de todos los errores antes de añadir nueva funcionalidad. Hacer entregas frecuentes.
Refactorización del código, es decir, reescribir ciertas partes del código para aumentar su legibilidad y mantenibilidad pero sin modificar su comportamiento. Las pruebas han de garantizar que en la refactorización no se ha introducido ningún fallo.
Propiedad del código compartida: en vez de dividir la responsabilidad en el desarrollo de cada módulo en grupos de trabajo distintos, este método promueve el que todo el personal pueda corregir y extender cualquier parte del proyecto. Las frecuentes pruebas de regresión garantizan que los posibles errores serán detectados.
A modo de iniciación, lo preferible es comenzar centrándose en lo siguiente:
1.Pruebas unitarias continuas, frecuentemente repetidas y automatizadas. Se aconseja escribir el código de la prueba antes de la codificación. Para el caso la librería con la que realizar las pruebas con la librería TestNG.
2. Corrección de todos los errores antes de añadir nueva funcionalidad. Hacer entregas frecuentes, en el caso realizar dichas entregas a través de Subversión en Eclipse.
3. Desarrollo iterativo e incremental . pequeñas mejoras, unas tras otras. En el caso una vez resueltos los puntos uno y dos, centrarse en la funcionalidad.
Fuentes:
Wikipedia: Desarrollo ágil de software
Wikipedia: programación extrema
Wikipedia: TDD, desarrollo dirigido por pruebas
Navegapolis: Gestion y procesos
Lectura recomendada: