30
Abr
15

Colaboración

a todos los que tengan twitter y puedan hacer el favor de darle rt al siguiente se los agradecería

 

28
Abr
15

Regresando

Después de más de un año de inactividad regresamos a subir contenidos.

Aquí estaremos, colaborando en lo posible

 

Gracias  totales

Writing Bad

14
Abr
14

Heartbleed

Heartbleed es, probablemente, una de las fallas de seguridad más graves en toda la historia de internet. En términos generales, consistía en un método a través del cual se podía robar información con mucha facilidad de los servicios más importantes del mundo. Aunque ya la resolvieron, los expertos recomiendan que la mayoría de las personas cambien sus contraseñas, pues muchos sitios se vieron comprometidos.
Es muy recomendable que las personas que tienen cuenta en los siguientes servicios cambien su contraseña lo más pronto que puedan: Facebook, Pinterest, Tumblr, Google, Yahoo, Gmail, servicios web de Amazon, Dropbox y Sound Cloud. Todos esas páginas usan el protocolo a través del cual se formó la vulnerabilidad. Ni Twitter ni Hotmail se vieron comprometidos por ello.
Sobra decir que la vulnerabilidad se haya manifestado en todos estos sitios no significa que nos van a hackear a todos, pero nunca sobra un saludable cambio de contraseña. Esa es una de las prácticas más recomendadas por los especialistas en seguridad y la mejor manera de evitar que lo hackeen. Recuerden que en algunos de esos sitios ustedes pueden tener información bancaria y otros datos que pueden resultar comprometidos.

Todas las empresas ya anunciaron que arreglaron el problema, lo que quiere decir que la nueva contraseña será segura.

02
Oct
13

MVC – Model View Controller (Patrón de diseño)

MVC es un patrón de diseño, que se ubica en la categoría de patrones arquitectónicos; este patrón se especifica bajo la proposición de dividir la aplicación en tres tipos de elementos, el modelo, las vistas (GUIs) y controladores. Estos elementos están separados por límites abstractos lo que convierte a MVC más paradigma que patrón, ya que la comunicación entre sí a través de esos límites no se especifica más. La manera en que los elementos dentro de MVC se comunican difieren y no sólo lo diferencia el tipo de aplicación que se está describiendo (Desktop, WEB),  sino también por la parte de la aplicación que actualmente está mirando (frontend, backend).

MVC

MVC

Sin embargo, en el centro de cada arquitectura MVC se encuentran presentaciones separadas lo que declara una división especifica entre los objetos de dominio que modelan nuestra percepción del mundo real (modelo de objetos), y la presentación de dichos objetos que son los elementos de la GUI que vemos en la pantalla (objetos de vista).

MVC define la separación de estos tres tipos de elementos:

  1. Modelo: elementos (objetos) que contienen los datos y definen la lógica para manipular dichos datos. A menudo los objetos tienen una naturaleza reutilizable, distribuida, persistente y portátil para una variedad de plataformas.
  2. Vista: hace referencia a los elementos que representan algo visible en la interfaz de usuario, por ejemplo, un panel o botones. Con el fin de mostrar datos de los objetos de modelo es posible que desee crear sus propios objetos personalizados, como un gráfico, por ejemplo.
  3. Controlador: actúa como un mediador entre los objetos del modelo y la vista . Un objeto Controller comunica datos de ida y vuelta entre los objetos del modelo y de la vista. Un controlador también realiza todas las tareas específicas de la aplicación, tales como la entrada del usuario o la carga de procesamiento de datos de configuración. Por lo general un se puede ver un controlador por aplicación o ventana, en muchas aplicaciones, el controlador está estrechamente acoplado a la vista. Dado que los controladores son específicos de aplicaciones por lo general es muy difícil encontrar reutilización en otras aplicaciones.

Diseño de una aplicación estrictamente de acuerdo con MVC no es siempre recomendable. Si está diseñando un programa intensivo de gráficos, probablemente tendremos muy pocas vistas y clases de modelo mucho más de lo que sugiere MVC. y al programar una aplicación muy simple es común combinar el controlador con las clases de vista. por otro lado el paradigma MVC no es necesariamente específico para lenguajes de programación orientados a objetos. Por ejemplo, una aplicación escrita en PHP no siendo orientada a objetos, también puede seguir los principios del patrón Modelo Vista Controlador utilizando sistemas de plantillas o marcos MVC diseñado para PHP.

El campo de aplicación de este patrón es bastante amplio casi se puede utilizar en cada aplicación. por supuesto dependiendo de la aplicación puede que algunas clases deben acoplarse a otras más que en otras aplicaciones, sin embargo, en general, siempre es una buena idea estructurar la aplicación en orden a MVC.

El patrón MVC en su implementación embebe diferentes patrones dependiendo de la  naturaleza de la aplicación que se está diseñando. Es común encontrar cosas como Intercepting Filters, View Helpers, Composite Views, Front Controllers, Value Objects, Session facades, Business Delegates y Data Access Objects que son utilizados por el patrón de arquitectura MVC, dentro de las cuales podemos resaltar:

Observer: este patrón es usado entre el Modelo y la Vista. Cuando los datos que están almacenados en los objetos del modelo sufren cambios, los objetos de la vista tienen que ser notificados y/o actualizados con respecto a la información con los cambios más reciente. Con el fin de mantener el acoplamiento entre los componentes Modelo/Vista y también debido al hecho de no tener varias instancias de objetos Vistas, el patrón Observer es el candidato ideal para lograr esto.

Estrategy: frecuente mente se implementa a nivel de modelo. El patrón DAO (Data Acces Object) es una forma del patrón de Estrategy que es utilizado  sobre todo por el modelo para acceder a diferentes formas de fuentes de datos. Por ejemplo, una base de datos MySQL/PostgreSQL, o archivos XML  almacenados en el disco.

Composite: utilizado por la Vista. No puede existir diferentes tipos de vistas dentro de un sistema diseñado de acuerdo con MVC, y alineandose a la finalidad de que todas las implementaciones sean compuestas y cambiadas a petición en tiempo de ejecución, se utiliza el patrón de Composite.

EJEMPLO DEL PATRÓN MVC EN JSP 

Ejemplo MVC en JSP

Ejemplo MVC en JSP

Referencias

Applications Programming in Smalltalk-80(TM)

Modelo Vista Controlador[Wikipedia]

The Ohio State University Software Development in Java Course 2009[Lecture 23]

Seminar Software Entwurf – Leif Singer

Designing Enterprise Applications with the J2EE Platform

Pattern Concepts – Oracle

16
Sep
13

Patrones Arquitectónicos

Los patrones arquitectónicos se utilizan para expresar una estructura de organización base o esquema para un  software. Proporcionando un conjunto de sub-sistemas predefinidos, especificando sus responsabilidades, reglas, directrices que determinan la organización, comunicación, interacción y relaciones entre ellos.

Los patrones arquitectónicos heredan mucha de la terminología y conceptos de patrones de diseño, pero se centran en proporcionar modelos y métodos re-utilizables específicamente  para la arquitectura general de los sistemas de información. En otras palabras quiere decir que a diferencia de los patrones de diseño estas son plantillas incompletas y no se pueden aplicar directamente al código con modificaciones meramente contextuales. Los patrones arquitectónicos a su vez se salen del código puro de la aplicación y suben e incluyen software, hardware, redes, inclusos las personas.

Dentro de los patrones arquitectónicos podemos encontrar:

  • Modelo Vista Controlador: es uno de los modelos más antiguos (Smalltalk-80)  y por lo tanto se convirtió en uno de los patrones fundamentales para el desarrollo de software. MVC a grandes trazos, separa las preocupaciones con respecto a los datos (modelo) y la interfaz de usuario (vista/GUI), permitiendo modificaciones independientes en cada una  las partes sin afectar la otra, o sea, para que los cambios realizados en la interfaz de usuario (GUI) no afectan el manejo de datos, y los datos pueden ser reorganizados sin cambiar la interfaz de usuario.
  • Inyección de Dependencias: es un patrón que a pesar de ser relativamente nuevo es muy complejo. La utilización de inyección de dependencia en un proyecto es tan incidente, que puede modificar en grandes proporciones la arquitectura, de modo que se hace prudente una planificación a futuro sobre la utilización de este patrón. Este patrón puede dar la impresión de ir un poco «al revés», porque el mismo, se trata de una aplicación de la «Inversión de Control – IoC», concepto que hace exactamente eso, se invierte el flujo de control. El nombre de «la inyección de dependencia» en realidad se presta a confusión, ya que el modelo permite que se inyecte no dependencias en sí, sino en su lugar, la información para satisfacerlas la relación a las dependencias.
  • Arquitectura dirigida por eventos (Event-driven architecture o EDA): es un patrón de arquitectura software que para orquestar su comportamiento se centra en torno a la producción, detección, consumo y respuestas ante «eventos». Teniendo en cuenta que un evento es: cualquier ocurrencia identificable que tiene un significado para el hardware o el software del sistema, en otras palabras, cualquier cambio de estado significante para el sistema. Y a su vez este cambio de estado puede ser conocido por otras aplicaciones en la arquitectura, o sea, que cada evento se propaga de manera inmediata a otras partes del sistema en la medida que sea necesario.
  • Arquitectura orientada a servicios: La ‘Arquitectura Orientada a Servicios de cliente’ (Service Oriented Architecture), es un concepto de arquitectura de software donde el software consta de una composición de servicios, prestaciones y reglas, y son los requisitos del negocio los que dictaminan la manera en la que estas se ínter-relaciona. Esta diseñado para que el sistema sea altamente escalable y flexible a nuevos requerimientos.

Referencias

http://www.omg.org/soa/Uploaded%20Docs/EDA/bda2-2-06cc.pdf

http://searchsoa.techtarget.com/definition/event-driven-architecture

http://download.boulder.ibm.com/ibmdl/pub/software/dw/webservices/ws-soa-whitepaper.pdf

http://download.microsoft.com/download/e/9/d/e9d163db-5c96-46bc-9263-aac62fc38831/Service%20Oriented%20Architecture.pdf

13
Sep
13

Become a Programmer, Motherfucker

Entre tantas páginas que visito ayer me encontré con esta. que a pesar de su publicidad fuera de lo común también brinda un buen contenido aunque está todo en inglés:

Become a Programmer, Motherfucker

Become a Programmer, Motherfucker

11
Sep
13

Delegation (Patrón de diseño)

Para cerrar la parte de patrones fundamentales, trataremos el patrón de delegación, este patrón ha sido descrito como una manera de realizar «herencia múltiple manualmente mediante composición de objetos».

Delegation, se trata de una técnica en la que un objeto permite mostrar cierto método al exterior, pero internamente la implementación o las acciones desencadenadas por el llamado de este método se delega a otro objeto de una clase distinta pero asociado. La delegación es utilizada como un mecanismo para centralizar en torno a un solo objeto  los compartimentos(métodos) de varios objetos donde dichos comportamientos mantienen cierto nivel de relación.

 

 

Podemos implementar Delegation de dos maneras, (1) la primera es haciendo uso de objetos dentro de otro (composición) y (2) la otra manera es la utilización de interfaces; permitiendo que la implementación del patrón pueda ser realizada, sin embargo en ocasiones la relación deseada entre clases es de contención en vez de herencia. Delegation no se limita solo a escenarios donde se debe evitar la herencia múltiple (la herencia múltiple no es permitida en Java) , pero se puede ver como una alternativa general a la herencia.

Este patrón se usa comúnmente en casos donde:

  • Se desea reducir el acoplamiento de métodos para una clase.
  • Existen componentes que tienen comportamientos similares, pero que en un futuro es posible que se realicen cambios.
  • Se desea remplazar la herencia, generalmente se usa la delegación como alternativa a la herencia.

Hay que tener en cuenta que la herencia a pesar de ser una buena estrategia para ser utilizada cuando existe una estrecha relación entre las clases involucradas, no es recomendada cuando la relación no es tan estrecha, ya que se crea una lazo de dependencia directa entre las clases; por otra parte la delegación es la forma más flexible para expresar una relación entre clases.

 

Ejemplo con clases:

package ingenio.ds.examples.patrones;
public class Clases{
	public static void main(String args[]){
		System.out.println("Usando el SuperAutoMovil");
		SuperAutoMovil superAutoMovil= new SuperAutoMovil();
		System.out.println("-- Funciones de AutoMovil:");
		superAutoMovil.iniciarMotor();
		superAutoMovil.andar();
		
		System.out.println();
		System.out.println("-- Funciones de Subergible:");
		superAutoMovil.navegar();
		superAutoMovil.navegarMasProfundo();
		superAutoMovil.navegarMasSuperficial();
		
		System.out.println();
		System.out.println("-- Funciones de Helicoptero:");
		superAutoMovil.volar();
		superAutoMovil.volarMasAlto();
		superAutoMovil.volarMasBajo();
	}
}

class Barco{
	public void iniciarMotor(){
		System.out.println("Barco: iniciando motor");
	}
	public void andar(){
		System.out.println("Barco: andando");
	}
}

class Automovil{
	public void iniciarMotor(){
		System.out.println("Automovil: iniciando motor");
	}
	public void andar(){
		System.out.println("Automovil: andando");
	}
}

class Helicoptero {
	public void iniciarMotor(){
		System.out.println("Helicoptero: iniciando motor");
	}
	public void andar(){
		System.out.println("Helicoptero: andando");
	}
	public void descender(){
		System.out.println("Helicoptero: descendiendo");
	}	
	public void ascender(){
		System.out.println("Helicoptero: ascendinedo");
	}
}

class Subergible extends Barco{
	public void descender(){
		System.out.println("Subergible: descendiendo");
	}	
	public void ascender(){
		System.out.println("Subergible: ascendinedo");
	}
}


class SuperAutoMovil extends Automovil{
	private Subergible  sumergible;
	private Helicoptero helicoptero;
	
	public SuperAutoMovil(){
		sumergible =new Subergible ();
		helicoptero=new Helicoptero();
	}
	
	public void andar(){
		super.iniciarMotor();
		super.andar();
	}
	
	public void navegar(){
		sumergible.iniciarMotor();
		sumergible.andar();
	}
	
	public void volar(){
		helicoptero.iniciarMotor();
		helicoptero.andar();
	}
	
	public void volarMasAlto(){
		helicoptero.ascender();
	}
	
	public void volarMasBajo(){
		helicoptero.descender();
	}
	
	public void navegarMasSuperficial(){
		sumergible.ascender();
	}
	
	public void navegarMasProfundo(){
		sumergible.descender();
	}
}

 
Ejemplo con interfaces:

package ingenio.ds.examples.patrones;

public class Interfaces {
	public static void main(String args[]) {
		Automovil automovil = new Automovil();
		automovil.andar();
		automovil.setMotor(new MotorElectrico());
		automovil.andar();
	}
}

interface Motor{
	public void andar();
}

class MotorVapor implements Motor {
	public void andar() {
		System.out.println("Aumenta persión");
		System.out.println("Aumenta velocidad");
	}
}

class MotorElectrico implements Motor {
	public void andar() {
		System.out.println("Aumenta revoluviones");
		System.out.println("Aumenta velocidad");
	}
}

class  Automovil{
	private Motor motor = new MotorVapor();
	
	public void andar() {
		motor.andar();
	}
	
	public void setMotor(Motor motorNuevo) {
		motor = motorNuevo;
	}
}

 

06
Sep
13

Programar en simple (tutoriales java EE)

Excelente fuente de recurso Java EE…

Chapter 1: Introduction

Chapter 2: Just Enough Of: Database Design

Chapter 3: JPA 2.0( Java Persistence API 2.0)

Chapter 4: EJB 3.1( Enterprise Java Beans 3.1)

Chapter 5: JSF 2.0( Java Server Faces 2.0)

Chapter 6: JMS ( Java Message Service)

Chapter 7: JAX-RS( Java API For RESTful Web Services)

Chapter 8: CDI( Contexts And Dependency Injection)

 

 

06
Sep
13

Container (Patrón de diseño)

Container o patrón de contenedores, Un contenedor es un objeto creado para contener otros objetos  y permite agregar, acceder, modificar, eliminar, en otras palabras, un contenedor debe almacenar otros objetos y permitir su gestión a través de los métodos proporcionados por la clase contenedora [en java ya existe la API Collections que describe una serie de contenedores] – colas, pilas, listas, vectores. Estos objetos (los elementos contenidos) por lo general son de tipo Object, y por herencia pueden ser de cualquier tipo  incluso pueden ser de la misma clase del contenedor. Cada Container debe implementar algún tipo de iterador asociado para permitir recorrer los elementos contenidos.

El término contenedor en la programación informática moderna realidad puede referirse a muchas cosas:

  • Los programadores de Java, C# suelen llamar a este tipo de clases de «colecciones» en lugar de «contenedores». la Java Collections Framework proporciona implementaciones para muchos tipos de clases Container, una implementación típica de una clase de colección en Java sería ArrayList o HashMap.
  • Dentro del Framework  Spring los contenedores representan conceptos de más alto nivel, tales como la inversión de control (IoC). una explicación (en inglés) de lo que es IoC e inyección de dependencias  Inversion of Control Containers and the Dependency Injection pattern [Martin Flower].
  • Beans Enterprise son componentes de software que se ejecutan en un entorno especial llamado un contenedor EJB. Los contenedores sirven de hots y gestionan un «enterprise bean» de la misma manera que el Java Web Server aloja un servlet o un navegador HTML alberga un applet de Java.

Los usos más comunes del patrón Container son:

  • Quiere representar un grupo de objetos como uno solo.
  • Desea reutilizar funcionalidades para almacenar diferentes tipos de objetos.

Todo el código está encapsulado en unsolo archivo java

package ingenio.ds.examples.patrones;

/*definición de la interfaz mensajero*/
package ingenio.ds.examples.patrones;
import java.util.Iterator;

public class Main {

    public static void main(String[] args) {
        // Contenedor de Integer
        Contenedor contenedorEntero = new Contenedor();
        contenedorEntero.agregar(1);
        contenedorEntero.agregar(2);
        contenedorEntero.agregar(3);

        //Contenedor de String, solo soporta objetos String
        //contenedorCadena.add(1); genera error de compilacion
        Contenedor contenedorCadena = new Contenedor();
        contenedorCadena.agregar("uno");
        contenedorCadena.agregar("dos");
        contenedorCadena.agregar("tres");

        //Contenedor de Object, soporta objetos de cualquier clase
        Contenedor conetendorObject =new Contenedor();
        conetendorObject.agregar(new Integer(0));
        conetendorObject.agregar(new Double(0));
        conetendorObject.agregar(false);
        conetendorObject.agregar("String value");
        conetendorObject.agregar(0F);

       imprimir(contenedorEntero);
       imprimir(contenedorCadena);
       imprimir(conetendorObject);
    }

    public static void imprimir(Contenedor contenedor){
    	//Obtenemos el iterador
    	Iterator iterador = contenedor.iterador();
    	System.out.println("Container: ");
        while (iterador.hasNext()) {
        	Object elemento=iterador.next();
            System.out.println(elemento.getClass() +" - " + elemento);
        }
    }
}

class Contenedor {

	protected Nodo nodoInicial = null;
    protected Nodo nodoFinal = null;

    private class Nodo {
        private E elemento;
        Nodo siguiente = null;
        Nodo anterior = null;

        public Nodo(E elemento) {
            this.elemento = elemento;
        }
    }

    private class Iterador implements Iterator {
        protected Nodo nodoActual = nodoInicial;

		//retorna si tiene mas elemento
        public boolean hasNext() {
            return nodoActual != null;
        }

        //retorna el siguiente elemento
        public E next() {
            if (nodoActual == null) {
                return null;
            }
            E elemento = nodoActual.elemento;
            nodoActual = nodoActual.siguiente;
            return elemento;
        }

        //elimina el ultimo elelento retornado
        public void remove() {
            nodoActual.anterior.siguiente = nodoActual.siguiente;
            nodoActual.siguiente.anterior = nodoActual.anterior;
        }
    }

    public void agregar(E o) {
        if (nodoInicial == null) {
            nodoFinal = nodoInicial = new Nodo(o);
        } else {
            Nodo newnode = new Nodo(o);
            newnode.anterior = nodoFinal;
            nodoFinal = nodoFinal.siguiente = newnode;
        }
    }

    public Iterator iterador() {
        return new Iterador();
    }
}
23
May
13

SILK ICONS set de Iconos

En una aplicación es muy importante mantener un estándar en los iconos, y muchos de los programadores que conozco carecen de la habilidad para diseñar a nivel gráfico (al igual que carecen de la estética). Recientemente me encontré esta página donde existen set de iconos de mil iconos y que está bajo licencia  Creative Commons Attribution 2.5 License, o sea que solo requiere que haga referencia el trabajo del autor para ser usado en cualquier propósito. aquí en enlace al set de iconos http://www.famfamfam.com/lab/icons/silk/

fam icons set

fam icons set

21
May
13

Jasper Report (virtualización y generación de reportes)

Una de las partes a veces menos preciada, dentro de un software son los reportes que de este podemos extraer. Los reportes son documento (que puede ser impreso, digital, audiovisual, etc.) que pretende transmitir información clara y entendible acerca del estado, las características y/o circunstancias de un suceso o asunto.

 

La manera más fácil de observar el estado actual de un negocio a través de su software son las dashboard o los reportes que podemos extraer de ellos. personalmente considero que la mejor suite de reportes que conozco es la Crystal Reports, pero con la que más experiencia tengo (y de la que voy a hablar en está publicación) es Jasper Reports.

 

Jasper es una poderosa herramienta open source totalmente escrita en java y se utiliza para la creación de informes, utiliza diversas clases de data sources, también permite incluir reportes dentro de otros, y exportarlos en los formatos más comunes como son XLS, PDF, RTF, CSV, XML, TXT  y HTML.

 

Existen dos herramienta totalmente visual que nos facilita la creación de nuestros reportes Jaspersoft Studio (basado en eclipse, y cual yo utilizo) y el iReport Designer (basado en netbeans).  No entraremos en como crear reportes y que puedo hacer o no con Jasper, primero pasaremos por hacer un reporte un listado normal y como exportarlo en un formato de los anteriores mencionados; Utilizando el mismo ejemplo departamento-empleado (utilizado ya en más de una ocasión).

 

Desde está dirección podemos descargar Jasper http://sourceforge.net/projects/jasperreports/?source=dlp, jasper utiliza muchas bibliotecas las cuales también debemos incluir en nuestro classpath.

El resto de la configuración es tomada del ejemplo base (MVC en JSP), nos centraremos especialmente en lo que tiene que ver con Jasper y la generación de reportes:

En este ejemplo generaremos un solo reporte reporte_empleados.  este reporte por formato incluye dos subreportes, uno que contiene la cabecera y otro que contiene el pie de página.

reportes

reportes

Nota: Por cada reporte se muestran dos archivos uno es el archivo con el código editable y el otro es el archivo resultande de la compilación.

cabecera

cabecera (header.jrxml)

 

pie de página

pie de página (footer.jrxml)

 

reporte empleados

reporte empleados (reporte_empleados.jrxml)

 

Nota: los iconos  2013-05-21_11h15_34 indican que se está haciendo referencia a un sub-reporte  en este caso cabecera y pie de página respectivamente.

los archivos de reporte de jasper se crean en un formato .jrxml que luego de compilarlo pasa a ser .jasper se puede usar cualquiera de los dos para la generación del reportes, personalmente prefiero los .jasper porque ya están compilados y es un poco más rápido.

También hay que tener en cuenta que como estamos trabajando con Java, a los reportes debemos especificarle que estamos trabajando con ese lenguaje. Y para los reportes cuando los exportamos en HTML a las imágenes (en este caso el logo) le seteamos que sean Lazy.

Lenguaje java

Lenguaje java

Lazy

Lazy

A nivel de GUI  se creo una para generar el reporte de empleados, cuando damos clic en el botón «Generar» de Listado de empleados.

generar reportes

generar reportes

Nota: el único botón que funciona es el de listado de empleados

generar_reporte.jsp

<form action="<%=application.getAttribute("CONTROLLER").toString()%>/Generar/Reporte" method="post" enctype="application/x-www-form-urlencoded">
    <table width="100%" border="0" cellspacing="0" cellpadding="5">
        <tr>
            <td valign="top">
			Listado de empleados
            </td>
            <td>
                <select name="tipo">
                    <option value="pdf">pdf</option>
                    <option value="rtf">rtf</option>
                    <option value="xls">xls</option>
                    <option value="html">html</option>
                    <option value="xml">xml</option>
                    <option value="csv">csv</option>
                    <option value="txt">txt</option>
                </select>
            </td>
            <td>
                <input name="reporte" type="hidden" value="empleados">
                <input type="submit" value="Generar">
            </td>
        </tr>
    </table>
</form>

<form action="<%=application.getAttribute("CONTROLLER").toString()%>/Generar/Reporte" method="post" enctype="application/x-www-form-urlencoded">
    <table width="100%" border="0" cellspacing="0" cellpadding="5">
        <tr>
            <td valign="top">
			Listado de departamentos
            </td>
            <td>
                <select name="tipo">
                    <option value="pdf">pdf</option>
                    <option value="rtf">rtf</option>
                    <option value="xls">xls</option>
                    <option value="html">html</option>
                    <option value="html">xml</option>
                    <option value="html">csv</option>
                    <option value="txt">txt</option>
                </select>
            </td>
            <td>
                <input name="reporte" type="hidden" value="departamentos">
                <input name="reporte" type="button" value="Generar">
            </td>
        </tr>
    </table>
</form>

A nivel de Actions se creo uno para escribir el reporte en la salida del response GenerarReporte; esta clase se encarga de escribir por la salida el reporte.

GenerarReporte.java

package org;

//clases para que sea servlet
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.io.Serializable;
import javax.servlet.ServletException;
import java.util.HashMap;

public class GenerarReporte extends Action implements Serializable {

    public void run() throws ServletException, IOException {
        try {
            String reporte = request.getParameter("reporte");
            String tipo = request.getParameter("tipo");
            /*la direccion local a la imagen del logo*/
            ReportGenerator.DIRECCION_LOGO=application.getRealPath("/shared/images/ids_report_logo.png");
            /*la direccion local de la carpeta donde se encuentral los reportes*/
            ReportGenerator.DIRECCION_REPORTES=application.getRealPath("/shared/report/")+ File.separator;

            if (tipo.matches("pdf")) {
                response.setContentType("application/pdf");
                ReportGenerator.FORMATO_REPORTE = ReportGenerator.FORMATO_REPORTE_PDF;
            } else if (tipo.matches("rtf")) {
                response.setContentType("application/rtf");
                ReportGenerator.FORMATO_REPORTE = ReportGenerator.FORMATO_REPORTE_RTF;
            } else if (tipo.matches("xls")) {
                response.setContentType("application/vnd.ms-excel");
                ReportGenerator.FORMATO_REPORTE = ReportGenerator.FORMATO_REPORTE_XLS;
            } else if (tipo.matches("html")) {
                response.setContentType("text/html");
                ReportGenerator.FORMATO_REPORTE = ReportGenerator.FORMATO_REPORTE_HTML;
                /*si elreporte es HTML la utilizamos la url para acceder a la imagen*/
                ReportGenerator.DIRECCION_LOGO=request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + request.getContextPath()+"/shared/images/ids_report_logo.png";
            } else if (tipo.matches("xml")) {
                response.setContentType("application/xml");
                ReportGenerator.FORMATO_REPORTE = ReportGenerator.FORMATO_REPORTE_XML;
            } else if (tipo.matches("csv")) {
                response.setContentType("text/csv");
                ReportGenerator.FORMATO_REPORTE = ReportGenerator.FORMATO_REPORTE_CSV;
            } else if (tipo.matches("txt")) {
                response.setContentType("text/plain");
                ReportGenerator.FORMATO_REPORTE = ReportGenerator.FORMATO_REPORTE_TXT;
            }
            response.setHeader("Content-disposition", "attachment");
            response.setHeader("filename", reporte + "." + tipo);
            /*mandamos a crear el reporte*/
            byte[] reporteBytes = ReportGenerator.createReport(reporte, new HashMap(), model);
            OutputStream outputStream = response.getOutputStream();
            /*escribimos el reporte*/
            outputStream.write(reporteBytes);
            outputStream.flush();
        } catch (Exception ex) {
            throw new ServletException("error en GenerarReporte ", ex);
        }
    }
}

A nivel de utilidades se utiliza la clase ReportGenerator, ReportGenerator es la clase donde generamos el reporte en un formato especifico. cada formato tiene sus particularidades aunque funcionalmente y para nuestro ejemplo solo necesitamos modificar tres de estos:

exporter = new JRHtmlExporter();
exporter.setParameter(JRHtmlExporterParameter.IS_USING_IMAGES_TO_ALIGN, Boolean.FALSE);

Los reportes en HTML sino se le especifica  el parámetro IS_USING_IMAGES_TO_ALIGN a falso, este utilizará unas imágenes en blanco para darle espaciamiento al reporte añadiendo una lógica que para mi parecer es innecesaria (o lo ha sido hasta el momento).

exporter = new JRTextExporter();
exporter.setParameter(JRTextExporterParameter.PAGE_HEIGHT, new Integer(70).floatValue());
exporter.setParameter(JRTextExporterParameter.PAGE_WIDTH, new Integer(70).floatValue());
exporter.setParameter(JRTextExporterParameter.CHARACTER_WIDTH, new Integer(15).floatValue());
exporter.setParameter(JRTextExporterParameter.CHARACTER_HEIGHT, new Integer(15).floatValue());

Los reportes de tipo texto necesitan un tamaño de página y de carácter estos valores no están por defecto y sino son seteados lanzará una excepción.

exporter = new JRXlsExporter();
exporter.setParameter(JRXlsExporterParameter.IS_ONE_PAGE_PER_SHEET, Boolean.FALSE);
exporter.setParameter(JRXlsExporterParameter.IS_DETECT_CELL_TYPE, Boolean.TRUE);
exporter.setParameter(JRXlsExporterParameter.IS_WHITE_PAGE_BACKGROUND, Boolean.FALSE);
exporter.setParameter(JRXlsExporterParameter.IS_REMOVE_EMPTY_SPACE_BETWEEN_ROWS, Boolean.TRUE);
exporter.setParameter(JRXlsExporterParameter.IS_IGNORE_CELL_BORDER, Boolean.FALSE);

Por estética más que por otra cosa esta es la configuración que utilizo para generar Excel desde Jasper (aunque para los reportes en realidad utilizo JExcel o POI directamente).

package org;

import java.util.Map;
import java.io.File;
import java.io.ByteArrayOutputStream;
import net.sf.jasperreports.engine.JRParameter;
import net.sf.jasperreports.engine.JasperReport;
import net.sf.jasperreports.engine.JasperPrint;
import net.sf.jasperreports.engine.fill.JRFileVirtualizer;
import net.sf.jasperreports.engine.util.JRLoader;
import net.sf.jasperreports.engine.JasperFillManager;
import net.sf.jasperreports.engine.JRExporter;
import net.sf.jasperreports.engine.JRExporterParameter;
import net.sf.jasperreports.engine.export.JRCsvExporter;
import net.sf.jasperreports.engine.export.JRHtmlExporter;
import net.sf.jasperreports.engine.export.JRHtmlExporterParameter;
import net.sf.jasperreports.engine.export.JRPdfExporter;
import net.sf.jasperreports.engine.export.JRRtfExporter;
import net.sf.jasperreports.engine.export.JRXlsExporter;
import net.sf.jasperreports.engine.export.JRXlsExporterParameter;
import net.sf.jasperreports.engine.export.JRXmlExporter;
import net.sf.jasperreports.engine.export.JRTextExporter;
import net.sf.jasperreports.engine.export.JRTextExporterParameter;

public class ReportGenerator {

    public static Integer FORMATO_REPORTE = 1;
    public final static Integer FORMATO_REPORTE_PDF = 1;
    public final static Integer FORMATO_REPORTE_XLS = 2;
    public final static Integer FORMATO_REPORTE_RTF = 3;
    public final static Integer FORMATO_REPORTE_HTML = 4;
    public final static Integer FORMATO_REPORTE_XML = 5;
    public final static Integer FORMATO_REPORTE_CSV = 6;
    public final static Integer FORMATO_REPORTE_TXT = 7;
    public static String DIRECCION_LOGO = null;
    public static String DIRECCION_REPORTES = null;
    private static JRFileVirtualizer reportVirtualizer = null;

    public static byte[] createReport(String nombreReporte, Map parametros, Model model) throws Exception {
        /*la virtualizacion no es obligatoria*/
        if (reportVirtualizer == null) {
            /*y de los tres metodos para virtualizar reportes prefiero la de archivos.
             utilizamos una carpeta en disco para ello*/
            String urlReportes = System.getProperty("user.home") + File.separator + "ids" + File.separator + "temp";
            File carpeta = new File(urlReportes);
            File[] archivos = carpeta.listFiles();
            /*eliminamos el contenido de dicha carpeta*/
            if(archivos!=null){
            	 for (File file : archivos) {
	                try {
	                    file.delete();
	                } catch (Exception e) {
	                    e.printStackTrace();
	                }
	            }
            }

            /*declaramos el virtualizador*/
            reportVirtualizer = new JRFileVirtualizer(10, urlReportes);
        }

        parametros.put(JRParameter.REPORT_VIRTUALIZER, reportVirtualizer);
        parametros.put("direccion_logo", DIRECCION_LOGO);
        parametros.put("titulo", nombreReporte.toUpperCase());
        parametros.put("direccion_reportes", DIRECCION_REPORTES);
        /*cargamos el archivo jasper*/
        JasperReport report = (JasperReport) JRLoader.loadObject(DIRECCION_REPORTES + "reporte_" + nombreReporte + ".jasper");
        /*cargamos la informacion*/
        JasperPrint jasperPrint = JasperFillManager.fillReport(report, parametros, model.getConexion());
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        JRExporter exporter = null;
        /*configuramos la impresion del reporte dependiendo del formato*/
        if (FORMATO_REPORTE == FORMATO_REPORTE_PDF) {
            exporter = new JRPdfExporter();
        } else if (FORMATO_REPORTE == FORMATO_REPORTE_RTF) {
            exporter = new JRRtfExporter();
        } else if (FORMATO_REPORTE == FORMATO_REPORTE_HTML) {
            exporter = new JRHtmlExporter();
            exporter.setParameter(JRHtmlExporterParameter.IS_USING_IMAGES_TO_ALIGN, Boolean.FALSE);
        } else if (FORMATO_REPORTE == FORMATO_REPORTE_XML) {
            exporter = new JRXmlExporter();
        } else if (FORMATO_REPORTE == FORMATO_REPORTE_CSV) {
            exporter = new JRCsvExporter();
        } else if (FORMATO_REPORTE == FORMATO_REPORTE_TXT) {
            exporter = new JRTextExporter();
            /*para los reportes en texto debemos expresar el tamaño de la pagina*/
            exporter.setParameter(JRTextExporterParameter.PAGE_HEIGHT, new Integer(70).floatValue());
            exporter.setParameter(JRTextExporterParameter.PAGE_WIDTH, new Integer(70).floatValue());
            exporter.setParameter(JRTextExporterParameter.CHARACTER_WIDTH, new Integer(15).floatValue());
            exporter.setParameter(JRTextExporterParameter.CHARACTER_HEIGHT, new Integer(15).floatValue());
        } else if (FORMATO_REPORTE == FORMATO_REPORTE_XLS) {
            exporter = new JRXlsExporter();
            /*para los reportes en excel para una mejor visualizacion utilizo esta configuracion*/
            exporter.setParameter(JRXlsExporterParameter.IS_ONE_PAGE_PER_SHEET, Boolean.FALSE);
            exporter.setParameter(JRXlsExporterParameter.IS_DETECT_CELL_TYPE, Boolean.TRUE);
            exporter.setParameter(JRXlsExporterParameter.IS_WHITE_PAGE_BACKGROUND, Boolean.FALSE);
            exporter.setParameter(JRXlsExporterParameter.IS_REMOVE_EMPTY_SPACE_BETWEEN_ROWS, Boolean.TRUE);
            exporter.setParameter(JRXlsExporterParameter.IS_IGNORE_CELL_BORDER, Boolean.FALSE);
        }
        /*marcamos PDF como el formato predeterminado*/
        FORMATO_REPORTE = FORMATO_REPORTE_PDF;
        /*exportamos el reporte*/
        exporter.setParameter(JRExporterParameter.JASPER_PRINT, jasperPrint);
        exporter.setParameter(JRExporterParameter.OUTPUT_STREAM, baos);
        exporter.exportReport();
        /*obtenemos el byte[] que representa ek archivo*/
        if (baos != null) {
            /*llamamos al garbage collector*/
            System.gc();
            return baos.toByteArray();
        }
        return null;
    }
}

Otro tema que se esta incluyendo en esta clase es la Virtualización de los reportes en Jasper (la virtualización, data sources y el ciclo de vida de un reporte jasper serán tratados a futuro) tiene utilidad en caso de reportes muy grande ya que la información se carga en memoria y puede generar una OutOfMemoryException, la virtualización se utiliza para almacenar la información del reporte de manera temporal en otra disposición (afectando el rendimiento) garantizando que la memoria no se llenará a causa de Jasper y evitando un colapso en el sistema.

15
May
13

Monitorear el Servidor con Java Management eXtensions (JMX)

En ocasiones se hace necesario monitorear las actividades de nuestro servidor para conocer su estado, en mi caso la necesidad surgió cuando este al desplegar la aplicación comenzaba a bajar el rendimiento hasta colapsar. Actividad que en realidad es muy sencilla,  ya que java provee una API que nos permite realizarla; la Java Management eXtensions, La tecnología JMX proporciona una forma simple y estándar para gestionar recursos de aplicaciones, dispositivos y/o servicios. Debido a que la tecnología JMX es dinámica, se puede usar para controlar y gestionar los recursos a medida que se crean, se instalan o son  implementados. También puede utilizar la tecnología JMX para supervisar y gestionar la Máquina Virtual Java (Java VM).

Nota: En mi caso utilizo Tomcat sobre Windows 7.

Primero descargamos catalina-jmx-remote.jar, de igual manera (para mi la que mejor me pareció) descargamos visualvm que es el software que nos permitirá observar la actividad y estado del servidor.

 

Copiamos el catalina-jmx-remote.jar en la carpeta de las bibliotecas de nuestro server.

catalina-jmx-remote

catalina-jmx-remote

En el archivo de configuración del servidor llamado server.xml, ubicado en $CATALINA_BASE/conf/ (para mi caso C:\Program Files\Apache Software Foundation\Tomcat 6.0\conf\)  agregamos una linea donde describimos los puertos que utilizaremos para realizar la conexión:

 

<Listener className=»org.apache.catalina.mbeans.JmxRemoteLifecycleListener» rmiRegistryPortPlatform=»10001″ rmiServerPortPlatform=»10002″/>

listener

listener

Nota: por lo generar esta linea ya aparece incluida en el archivo server.xml como un comentario.

 

 

Modificamos los parámetros con los que inicia el servidor  para llamar a las opciones de JMX (las cuales pueden ser modificadas a necesidad pero)   para mi caso agregué las siguientes lineas a los parámetros con los que se inicia:

-Dcom.sun.management.jmxremote
-Dcom.sun.management.jmxremote.port=6060
-Dcom.sun.management.jmxremote.authenticate=true
-Dcom.sun.management.jmxremote.ssl=false
-Dcom.sun.management.jmxremote.password.file=C:\Program Files\Apache Software Foundation\Tomcat 6.0\conf\jmxremote.password
-Dcom.sun.management.jmxremote.access.file=C:\Program Files\Apache Software Foundation\Tomcat 6.0\conf\jmxremote.access

Nota: si -Dcom.sun.management.jmxremote.authenticate=false no es necesario describir los archivos de password y access

 

Hemos descrito dentro de los parámetros de inicio dos archivos: jmxremote.passwordjmxremote.access, archivos de texto plano que contienen las contraseñas y los tipos de acceso a JMX respectivamente:

 

 jmxremote.password   jmxremote.access
controlRole control
monitorRole monitor
  controlRole readwrite
monitorRole readonly

 

El siguiente paso a seguir es iniciar nuestro servidor. y conectarnos por JMX, en este punto iniciamos el visualvm y agregamos una nueva conexión JMX y listo ya estamos viendo el comportamiento del server.

Conectarse por JMX

Conectarse por JMX

los parámetros para la conexión serían:

Connection: service:jmx:rmi://localhost:10002/jndi/rmi://localhost:10001/jmxrmi
Username: monitorRole
Password: monitor

Server status

Server status

 

 

Nota: el archivo de password debe ser configurado para que sea de solo lectura y solo puede ser visto por el usuario que lo creo que a su vez debe ser el mismo usuario con el que inicia el servidor.

Referencias

09
May
13

Interface (Patrón de diseño)

Una interfaz se define como una «Conexión física y funcional entre dos aparatos o sistemas independientes» [Rae 2013], esta describe las operaciones (la cara al mundo) que una entidad puede realizar, de igual manera establece los limites, niveles de acceso y la manera en que se desarrolla la comunicación entre dos entidades, para nuestro caso caso dos piezas de software. Por lo general, se refiere a una abstracción que proporciona un activo de sí mismo a la parte exterior.

 

La idea principal de una interfaz es separar las funciones (firma de métodos) de las implementaciones (cuerpo del método) . Cualquier solicitud que coincida con la firma de la interfaz de un objeto también puede ser enviada a ese objeto, independientemente de su aplicación. Restando importancia a cual clase realiza la implementación y responda el llamado ya que el llamado se hace sobre la interfaz, brindando la capacidad de poder intercambiar fácilmente la clase que implementa la interfaz sin modificar el código donde se hace el llamado a dicha interfaz.

 

 

El concepto de una interfaz es fundamental en la mayoría de los lenguajes de programación orientados a objetos. En algunos, los objetos son conocidos sólo a través de sus interfaces de modo que no hay manera de acceder a un objeto sin tener que ir a través de su interfaz.

 

Los usos más comunes para las interfaces son:

  • Deseamos describir la el protocolo de comunicación de una clase fuera de su paquete.
  • Se debe cambiar la implementación de una funcionalidad en tiempo de ejecución.
  • Durante el diseño desconocemos cual será la implementación que se usará en tiempo de compilación.

 
Interfaces.java

package ingenio.ds.examples.patrones;

/*definición de la interfaz mensajero*/
interface Mensajero{
	/*definición del método enviar*/
	public void enviar(String titulo,String mensaje);
}

Clases.java

package ingenio.ds.examples.patrones;
import javax.swing.JOptionPane;

class Consola implements Mensajero{
	public void enviar(String titulo,String mensaje){
		System.out.println("Log : "+mensaje);
	}
}

class Popup implements Mensajero{
	public void enviar(String titulo,String mensaje){
		JOptionPane.showMessageDialog(null,
									 mensaje,
									 titulo,
									 JOptionPane.INFORMATION_MESSAGE);
	}
}

Main.java

package ingenio.ds.examples.patrones;

public class Main {
	/*describe el tipo de mensaje que usaremos*/
	public static String TIPO_MENSAJE="CONSOLA";
	public static void main(String argumentos[]){
		/*en este punto no conocemos la implementación que se usará para enviar el mensaje*/
		Mensajero mensajero=getMensajero();
		/*llamamos el método enviar */
		mensajero.enviar("Hola","Iniciar envio de mensaje");
		mensajero=getMensajero();
		mensajero.enviar("Hola","Patrón interface");
		mensajero=getMensajero();
		mensajero.enviar("Hola","Cerrar envio de mensaje");
	}

	public static Mensajero getMensajero(){
		/*dependiendo del 'contexto' retornará el mensajero necesario*/
		Mensajero mensajero=null;
		if(TIPO_MENSAJE=="CONSOLA"){
			mensajero=new Consola();
			TIPO_MENSAJE="POPUP";
		}else{
			mensajero=new Popup();
			TIPO_MENSAJE="CONSOLA";
		}
		return mensajero;
	}
}
07
May
13

Patrones Fundamentales

Son uno de los tipos de patrones de diseño. Se denominan fundamental, ya que contemplan funcionalidades básicas para los otros patrones, la mayoría de los las aplicaciones de los demás patrones se diseñan utilizando como base estos patrones de una manera u otra.

Algunos de los patrones fundamentales son trasladados a otras categorías: Proxy, Facade, Composite son ejemplo de ello. Mientras otros son incluidos dentro de las características propias de los lenguajes de programación por ejemplo la Collection en Java tiene varias implementaciones del patrón Container, a su vez el patrón Interface siempre ha estado vinculado a la Java desde su nacimiento. Se hace importante mantener la referencia de lo que en algún momento se reconoció como un patrón de diseño.

Interface: es un tipo especial de clase que le brinda al programador una manera más sencilla y específica de acceder a los atributos o funcionalidades de otras clases (entendiendo por interface como la cara accesible de una clase). En Java la implementación de este patrón es implícita en el uso del lenguaje, ya que sin «necesidad» de especificarlo el lenguaje se basa en sus interfaces para exponer la funcionalidad de una clase con el mundo exterior, y esto es una parte fundamental del lenguaje. A diferencia de C++, que tiene los archivos de cabecera para poder presentar la interfaz de una clase al exterior.

Container: es un objeto que nos permite agrupar múltiples elementos en una sola unidad, y al mismo tiempo brindando funcionalidades que nos permitan almacenar, recuperar, manipular, eliminar y comunicarnos con los datos agregados.  en Java contamos con la Java Collection Framework que es una arquitectura unificada para representar y manipular colecciones. Todos los frameworks de colecciones  contienen interfaces, implementaciones y algoritmos.

Delegation: este patrón permite la extensión de la funcionalidad de una clase a través de el uso de una clase contenedora que almacena a la clase original,así proporcionar las funcionalidades de la clase contenida a través del contenedor. Algunos autores lo describen como «Herencia realizada manualment   permitiendo a lenguajes como Java (que solo permiten herencia simple) simular la figura de herencia múltiple.

07
May
13

Track Back

Enviado desde un dispositivo BlackBerry® de Tigo

07
May
13

Patrones de diseño

En la ingeniería de software frecuentemente nos encontramos con problemas a nivel de desarrollo, que tal vez son escalado de una de las etapas anteriores. Muchos de estos problemas ya han sido solucionados en estrategias que gracias a su capacidad de implementarse en diferentes sistemas se convierten en patrones. Estos patrones los podemos definir como: “Los patrones de diseño son el esqueleto de las soluciones a problemas comunes en el desarrollo de software.” (¿Qué es un Patrón de Diseño?);     de igual manera los podemos definir como: modelo de objeto re-utilizable que ha sido útil en más de un contexto practico, brindando una solución a un problema en común.

En otras palabras los patrones son modelos que ha solucionado un problema en diferentes sistemas entonces se estandariza y brinda la posibilidad de replicar el mismo modelo para solucionar dicho problema en otro sistema independiente al contexto de este; se utiliza la palabra modelo ya que no todos los patrones son fácilmente adaptables a código. En los patrones se describe una plantilla (esqueleto) para resolver el problema, la destreza del programador tiene un papel fundamental para determinar el cuando y el como utilizarlos, ademas que ningún patrón es la piedra angular (no debes siempre utilizar el mismo) al momento de solucionar un problema, ya que en la practica un solo sistema puede utilizar varios patrones.

Para poder entender e implementar patrones en su plena concepción se debe tener claro que es programación orientada a objetos y cuales son sus principales propiedades: clase, objeto, método, paso de mensajes, herencia, encapsulamiento, polimorfismo y abstracción (aquí algunas).

Los patrones de diseño se clasifican en cinco categorías:

  1. Fundamentales: estos son utilizados en otros patrones para cumplir con el propósito establecido.
      1. Interface
      2. Container
      3. Delegation

     

  2. Arquitectónicos: estos patrones expresan una organización fundamental de la estructura del sistema, de igual manera proporcionan un conjunto de subsistemas especificando sus responsabilidades, reglas, directrices y relaciones entre ellos.
    1. Modelo Vista Controlador (MVC)
    2. Inyección de Dependencias

     

  3. Estructurales: describen como las clases y objetos se relacionan entre sí para trabajar entre ellos.
    1. Facade
    2. Decorator
    3. Proxy
    4. Data Access Object
    5. Transfer Object
    6. Composite
    7. Adapter

     

  4. de Creación: Ellos ayudan a hacer un sistema independiente de cómo se crean los objetos, que clases puedo instancias o sobre que objetos delego dicha responsabilidad.
    1. Factory Method
    2. Abstract Factory
    3. Object Pool
    4. Singleton
    5. Builder

     

  5. de Comportamiento: Se relacionan con los algoritmos y la asignación de responsabilidades entre los objetos, organización, nos permiten definir la comunicación entre los objetos y la manera en la que fluye la información entre ellos..
    1. Iterator
    2. Observer
    3. Event Listener
    4. Strategy
    5. Chain of Responsability
    6. Command
    7. Interpreter
    8. Mediator
    9. Memento
    10. State
    11. Visitor
    12. Template Method

Los patrones no son reglas estrictas son guías aplicables a nuestros desarrollos, incluso no siempre han sido bien recibidos por las comunidades académicas  recibiendo fuertes criticas, Estos nacen como el esfuerzo pos estandarizar lo que ya conocemos como mejores practicas, y muchas veces la implementación de patrones se desencadena en una duplicación innecesaria de código, para brindar una solución a un problema que en realidad pudo ser resulto por una restructuración del código y «Peter Norvig ofrece un argumento similar. Él demuestra que 16 de los 23 patrones en el libro Patrones de diseño (que se centra principalmente en C++) se han simplificado o eliminado (a través de apoyo lenguaje directo) en Lisp o Dylan».

Referencias

30
Abr
13

Redimensionamiento de imagenes en Java

Hace poco un compañero requería una funcionalidad que le entregase las fotos que tiene en el servidor en un tamaño «estándar» para que al momento de mostrarlas no hubiese unas muy grandes y otras pequeñas y así todas tendrían aproximadamente el mismo tamaño. entonces entre varias páginas pude construir una pequeña clase que:

  • Carga una imagen
  • Redimensiona una imagen
  • Guarda una imagen
  • Realiza una copia redimensionada de la imagen
package ingenio.ds.util.image;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;

public class ImageResizer {
	//Ancho máximo
    public static int MAX_WIDTH=800;
	//Alto máximo
    public static int MAX_HEIGHT=800;

	/*Este método es el de la magia recibe la ruta al archivo original y la ruta donde vamos a guardar la copia
	copyImage("C:\\Users\\IngenioDS\\Desktop\\test.png","C:\\Users\\IngenioDS\\Desktop\\Copia\\test2.png");*/

    public static void copyImage(String filePath, String copyPath) {
        BufferedImage bimage = loadImage(filePath);
        if(bimage.getHeight()>bimage.getWidth()){
        	int heigt = (bimage.getHeight() * MAX_WIDTH) / bimage.getWidth();
            bimage = resize(bimage, MAX_WIDTH, heigt);
        	int width = (bimage.getWidth() * MAX_HEIGHT) / bimage.getHeight();
            bimage = resize(bimage, width, MAX_HEIGHT);
        }else{
        	int width = (bimage.getWidth() * MAX_HEIGHT) / bimage.getHeight();
            bimage = resize(bimage, width, MAX_HEIGHT);
        	int heigt = (bimage.getHeight() * MAX_WIDTH) / bimage.getWidth();
            bimage = resize(bimage, MAX_WIDTH, heigt);
        }
        saveImage(bimage, copyPath);
    }
	
	/*
	Este método se utiliza para cargar la imagen de disco
	*/
    public static BufferedImage loadImage(String pathName) {
        BufferedImage bimage = null;
        try {
            bimage = ImageIO.read(new File(pathName));
        } catch (Exception e) {
            e.printStackTrace();
        }
        return bimage;
    }

    /*
	Este método se utiliza para almacenar la imagen en disco
	*/
	public static void saveImage(BufferedImage bufferedImage, String pathName) {
        try {
            String format = (pathName.endsWith(".png")) ? "png" : "jpg";
            File file =new File(pathName);
            file.getParentFile().mkdirs();
            ImageIO.write(bufferedImage, format, file);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
	
	/*
	Este método se utiliza para redimensionar la imagen
	*/
    public static BufferedImage resize(BufferedImage bufferedImage, int newW, int newH) {
        int w = bufferedImage.getWidth();
        int h = bufferedImage.getHeight();
        BufferedImage bufim = new BufferedImage(newW, newH, bufferedImage.getType());
        Graphics2D g = bufim.createGraphics();
        g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
        g.drawImage(bufferedImage, 0, 0, newW, newH, 0, 0, w, h, null);
        g.dispose();
        return bufim;
    }
}
30
Abr
13

Propiedades de la P.O.O. (Encapsulamiento)

El Encapsulamiento  es una de las características de la programación orientada a objetos, esta trata de reducir el nivel de cohesión entre clases a través de dos principios básicos:

1) ocultar la complejidad del código y

2) ocultar las fuentes de cambios; proporcionando una interfaz pública de la clase más fácil de usar.

El primer punto hace referencia a: que podemos utilizar una funcionalidad de la clase sin necesidad de conocer la naturaleza de la complejidad que se desarrolla al ejecutar dicha funcionalidad o sea que podemos ejecutar un método y esperar una respuesta de este sin conocer la lógica que se desarrolla para entregar dicha respuesta. El segundo punto hace referencia a que dicha complejidad puede cambiar incluso en su implementación, pero a nivel externo seguirá funcionando sin que los llamados a esta funcionalidad se de por advertidos, o sea que usamos un método de una clase e instalamos una nueva versión de dicha clase y puede que el código de dicho método tuviese una actualización pero a nosotros como usuarios de dicho método en realidad lo único que nos interesa es que el método ofrezca la misma respuesta.

En otras palabras el punto uno se refiere a que la clase provea los métodos para usar la lógica interna sin necesidad de  que conozcamos dicha lógica y el segundo punto hace referencia a que dicho código puede cambiar y no nos afecte en la manera que los hayamos usado.

Al momento de encapsular las abstracciones es un proceso de cuidado y debe hacerse de manera adecuada, ya que realizar la descripción de interfaces sin los niveles adecuados de encapsulación terminará causando dificultades a los cambios que se den de manera posterior. Así podemos entender a la encapsulación como un atributo que permite modificación, evolución, crecimiento de nuestro código, siempre y cuando respetemos la interfaz pública de nuestras clases ademas reducir la complejidad de las abstracciones. proporcionando una forma de ocultar los detalles de implementación y también nos ayudan a minimizar la interdependencia y facilitar el modificaciones a su vez brindando la libertad para cambiar lo que queramos del funcionamiento interno encapsulado.  podemos resumir la encapsulación en la siguiente premisa En la maximización de encapsulación, reduciendo al mínimo la exposición de los detalles de implementación.

La encapsulación es mucho más que getters y setters, y la naturaleza de esta va mucho más allá que la de proporcionar una interfaz pública a atributos privados. El sentido de los getters y setters no es para ocultar los datos en sí, en realidad es para ocultar los detalles de la implementación de cómo se manipula la información. Así, una vez más, lo que hacemos es proporcionar una interfaz pública a través del cual podemos acceder a estos datos.

el ejemplo más sencillo que se me puede ocurrir de encapsulamiento es:

package ingenio.ds.examples;

public class Main {

   public static void main(String argumentos[]){
		/*Al momento de acceder a la propiedad nombre del estudiante ya que es públi
		 *ca no tenemos ningún problema en tomar el valor. Y esta se nos mostrará c
		 *omo null.
		 *Al momento de acceder a la propiedad nombre del profesor este encapsula c
		 *ierta lógica que nos impide accesarla de manera directa y apersar que el
		 *valor es null el dato retornado es diferente.
		 */
		 Estudiante estudiante= new Estudiante();
		 Profesor profesor= new Profesor();
		 System.out.println("Nombre estudiante "+estudiante.nombre);
		 System.out.println("Nombre profesor   "+profesor.getNombre());
	}
}

class Estudiante {
	public String nombre;
	public String identificacion;
}

class Profesor{
	private String nombre;
	private String identificacion;

	public String getNombre(){
		if(nombre==null){
			return "NULO";
		}else if(nombre==""){
			return "N/A";
		}
		return nombre;
	}

	public String getIdentificacion(){
		if(identificacion==null || nombre==""){
			return "NO IDENTIFICADO";
		}
		return nombre;
	}

	public void setNombre(String nombre){
		this.nombre=nombre;
	}
	public void setIdentificacion(String identificacion){
		this.identificacion=identificacion;
	}
}

Referencias

http://en.wikipedia.org/wiki/Encapsulation_(object-oriented_programming)

http://www.javaworld.com/javaworld/jw-05-2001/jw-0518-encapsulation.html?page=9

http://java.about.com/od/workingwithobjects/a/accessormutator.htm

http://java.dzone.com/articles/why-encapsulation-matters

28
Abr
13

Propiedades de la P.O.O. (Polimorfismo parte 2)

Teniendo en cuenta todo lo expuesto en Propiedades de la P.O.O. (Interfaces)Propiedades de la P.O.O. (Clases abstractas) y Propiedades de la P.O.O. (Polimorfismo parte 1), a continuación revisaremos  como podemos realizar polimorfismo con clases abstractas.

Ademas revisamos como funciona la herencia múltiple en java.

Lo anterior es plasmado en el siguiente código:

Interfaces.java
Aquí describimos las interfaces con que vamos a trabajar

package ingenio.ds.examples;

//*definición de la interfaz mostrable*/
interface Mostrable{
	/*definición de una constante, debe ser 'static final' por convención se e
	 *scribre el nombre en mayuscula sostenida*/
	public static final boolean ES_MOSTRABLE=true;
	/*definición del método mostrar*/
	public void mostrar();
}

//*definición de la interfaz acelerable*/
interface Acelerable{
	/*definición de una constante, debe ser 'static final' por convención se e
	 *scribre el nombre en mayuscula sostenida y los espacios con '_' */
	public static final double RELACION_ACELERACION=0.2;
	/*definición del método acelerar*/
	public void acelerar(int segundos);
}

/*dentro de las interfaces también existe la figura de la herencia aunque en e
 *estas puede hacerse de manera multiple*/

interface AcelerableMostrable extends Mostrable,Acelerable{

	/*esta interfaz tiene  por herencia las constantes boolean ES_MOSTRABLE y
	 * double RELACION_ACELERACION */

	/*esta interfaz tiene  por herencia los métodos void mostrar() y void acel
	 *erar(int) */

}

Clases.java
Aquí implementamos las interfaces.

package ingenio.ds.examples;

abstract class Vehiculo implements AcelerableMostrable{
	String nombre;
	String tipoVehiculo;
	String fuenteEnergia;
	Double velocidadMaxima;
	Double velocidadActual;
	Double relacionAceleracion;
	int cantidadTripulacion;

	public Vehiculo(){
	}

	/*
	 *Este será el método general utilizado por todos vehículos que no implemen
	 *ten un método acelelar pópio, está es una implementación del metodo descr
	 *ito en la interfaz Acelerable
	 */
	public void acelerar(int segundos){
		System.out.println(" Acelerar vehículo .");
		for(int i=0;i<segundos;i++){
			velocidadActual=velocidadActual+(velocidadMaxima/2*relacionAceleracion);
			if(velocidadActual>velocidadMaxima){
				velocidadActual=velocidadMaxima;
				break;
			}
		}
	}

	public void mostrar(){
		System.out.println(" Información del vehículo");
		System.out.println(" Nombre ...........: "+nombre);
		System.out.println(" Tipo   ...........: "+tipoVehiculo);
		System.out.println(" Fuente de energía : "+fuenteEnergia);
		System.out.println(" Tripulación ......: "+cantidadTripulacion);
		System.out.println(" Velocidad máxima .: "+velocidadMaxima);
		System.out.println(" Velocidad actual .: "+velocidadActual);
	}
}

class VehiculoTerrestre extends Vehiculo{
	String tipoTerreno;

	public VehiculoTerrestre(){
		tipoVehiculo="Terrestre";
	}

	public void mostrar(){
		super.mostrar();
		System.out.println(" Tipo de terreno ..: "+tipoTerreno);
	}

}

class Bicicleta extends VehiculoTerrestre{
	String tipoBicicleta;
	int cantidadLlantas;
	String material;

	public Bicicleta(){
		nombre="Bicicleta";
		tipoTerreno="Terreno firme";
		fuenteEnergia="Propulsión humana";
		relacionAceleracion=0.04;
	}

	public void acelerar(int segundos){
		System.out.println(" Acelerar bicicleta ");
		System.out.println(" - Tomar aíre (MUCHO AÍRE) ");
		for(int i=0;i<segundos;i++){
			System.out.println(" - Aplicar más fuerza sobre el pedal ");
			System.out.println(" - Aplicar más fuerza sobre el otro pedal");
			velocidadActual=velocidadActual+(1+relacionAceleracion);
			if(velocidadActual>velocidadMaxima){
				velocidadActual=velocidadMaxima;
				break;
			}
		}
	}
}

class VehiculoAcuatico extends Vehiculo{
	String tipoNavegacion;

	public VehiculoAcuatico(){
		tipoVehiculo="Acuatico";
	}
}

class Submarino extends VehiculoAcuatico{
	String tipoSubmarino;

	public Submarino(){
		nombre="Submarino";
		fuenteEnergia="Propulsión mecánica";
		relacionAceleracion=0.15;
		tipoNavegacion="Bajo superficie";
	}

	public void mostrar(){
		super.mostrar();
		System.out.println(" Tipo de submari ..: "+tipoSubmarino);
	}

	public void acelerar(int segundos){
		System.out.println(" Acelerar submarino ");
		System.out.println(" - Inyecta combustible ");
		System.out.println(" - Gases  ");
		System.out.println(" - Chispa ");
		System.out.println(" - Aumentar presión en la combustión ");
		for(int i=0;i<segundos;i++){
			System.out.println(" - Aumentar revoluciones en las aspas ");
			velocidadActual=velocidadActual+relacionAceleracion;
			if(velocidadActual>velocidadMaxima){
				velocidadActual=velocidadMaxima;
				break;
			}
		}
	}
}

class VehiculoAereo extends Vehiculo{
	Double alturaMaxima;
	String tipoCarga;

	public VehiculoAereo(){
		tipoVehiculo="Aereo";
	}

}

class Avion extends VehiculoAereo{
	int cantidadMotores;
	String tipoAvion;

	public Avion(){
		nombre="Avión";
		fuenteEnergia="Motor";
		relacionAceleracion=0.3;
	}

	public void mostrar(){
		super.mostrar();
		System.out.println(" Tipo de avión ....: "+tipoAvion);
		System.out.println(" Cantidad de motore: "+cantidadMotores);
	}

	public void acelerar(int segundos){
		System.out.println(" Acelerar avión ");
		System.out.println(" - Inyecta combustible ");
		System.out.println(" - Gases  ");
		System.out.println(" - Chispa ");
		System.out.println(" - Aumentar presión en la combustión ");
		for(int i=0;i<segundos;i++){
			System.out.println(" - Aumentar revoluciones en el motor");
			velocidadActual=velocidadActual+(velocidadMaxima/2*relacionAceleracion);
			if(velocidadActual>velocidadMaxima){
				velocidadActual=velocidadMaxima;
				break;
			}
		}
	}
}

Main.java
Aquí dejamos que ocurra la maJia

package ingenio.ds.examples;

public class Main {

   	public static void main(String argumentos[]){
		//*Creamos instancias de las sub-clases Bicicleta, Avion, Submarino*/
		Avion v1=new Avion();
		Bicicleta v2=new Bicicleta();
		Submarino v3=new Submarino();

		//*seteamos valores para el Avion*/
		v1.velocidadActual=0.0001;
		v1.velocidadMaxima=850.0;
		v1.cantidadTripulacion=2;
		v1.cantidadMotores=4;
		v1.tipoAvion="Pasajeros";
		v1.alturaMaxima=10400.0;

		//*seteamos valores para la Bicicleta*/
		v2.velocidadActual=1.0;
		v2.velocidadMaxima=60.0;
		v2.cantidadTripulacion=1;
		v2.cantidadLlantas=2;
		v2.material="Aluminio/Fibra";
		v2.tipoBicicleta="Montañera";

		//*seteamos valores para el Submarino*/
		v3.velocidadActual=0.0001;
		v3.velocidadMaxima=460.0;
		v3.cantidadTripulacion=8;
		v3.tipoSubmarino="Militar";

		//*Creamos un arreglo de la super clase y agregamos las instancias de las sub clases*/
		Vehiculo[] vehiculos= new Vehiculo[]{v1,v2,v3};
		acelerar(vehiculos);
	}
	/*
	 *En las implementaciones de Mostrable o Acelerable no nos importa
	 *de que clase son los objetos lo único que tenemos en cuenta es q
	 *ue */
	public static void acelerar(AcelerableMostrable instancias[]){
		for(AcelerableMostrable instancia:instancias){
			instancia.mostrar();
			instancia.acelerar(6);
			/*Si la instancia es de tipo Vehiculo, obtenemos la velocidad actual despues de acelerar
			 *preguntamos en caso de que no sea una instancia de Vehiculo no realizar el casting (en
			 *este ejemplo no es necesario, pero es importante realizar esa verificación en tus códi
			 *gos) */
			if (instancia instanceof Vehiculo){
				System.out.println(" Velocidad final   ."+((Vehiculo)instancia).velocidadActual );
			}
		}
	}
}
28
Abr
13

etask.it: Herramienta en gestión de proyectos

Cada nunca hago promoción a na herramienta en el blog, pero en esta ocasión les hablaré de una que me ha parecido realmente buena. es una herramienta disponible como SaaS y me da la impresión que ha sido programada en Java con Ext-JS. está herramienta es de fácil uso, es ágil, intuitivaa y funcional pero no digo más, aquí les dejo el enlace a ETaskproject-1

28
Abr
13

Propiedades de la P.O.O. (Clases abstractas)

Las clases abstractas en cierta forma son muy parecidas a las interfaces y son muy parecidas a las clases normales.  Una clase abstracta puede tener o no métodos abstractos, no pueden ser instanciadas y son utilizadas como «plantilla» para otras clases ya que si pueden ser heredadas.

Son parecidas a las interfaces ya que podemos declarar métodos abstractos y de estos no especificar la implementación, lo que obliga a las sub-clases (no abstractas) a describir la implementación de dicho método(abstract void metodo();), todos los métodos de una interfaz son abstractos sin necesidad de decirlo de manera explicita.

Tanto las interfaces como las clases abstractas permiten implementar la figura de polimorfismo dentro del código, la diferencia mas notable que hay es que en las interfaces no se puede describir la implementación de un método y la declaración de sus variables deben ser final y estáticas, dejando así una «plantilla» en blanco para ser implementada totalmente por la clase que use dicha interfaz; y por otro lugar en las clases abstractas se comparte una porción de la implementación de los métodos; proveyendo parte de la funcionalidad y dejando la otra parte para ser implementada por la sub-clase. O sea una clase abstracta con todos los métodos abstractos debería ser declarada como interfaz, de igual manera una clase abstracta que no declare ningún método abstracto debe ser declarada como una clase normal.

package ingenio.ds.examples;

public class ClasesAbstractas {

   	public static void main(String argumentos[]){
		//*Creamos instancias de las sub-clases Bicicleta, Avion, Submarino*/
		VehiculoAereo v1=new VehiculoAereo();
		VehiculoTerrestre v2=new VehiculoTerrestre();
		VehiculoAcuatico v3=new VehiculoAcuatico();

		//*seteamos valores para el VehiculoAereo*/
		v1.nombre="Avión";
		v1.velocidadActual=0.0001;
		v1.velocidadMaxima=850.0;
		v1.cantidadTripulacion=2;
		v1.alturaMaxima=10400.0;

		//*seteamos valores para la VehiculoTerrestre*/
		v2.nombre="Automovil";
		v2.tipoTerreno="Desertico";
		v2.velocidadActual=1.0;
		v2.velocidadMaxima=60.0;
		v2.cantidadTripulacion=1;

		//*seteamos valores para el VehiculoAcuatico*/
		v3.nombre="Lancha";
		v3.velocidadActual=0.0001;
		v3.velocidadMaxima=460.0;
		v3.cantidadTripulacion=8;

		//*Creamos un arreglo de la super clase y agregamos
		//las instancias de las sub clases*/
		Vehiculo[] vehiculos= new Vehiculo[]{v1,v2,v3};
		mostrar(vehiculos);
	}

	public static void mostrar(Vehiculo instancias[]){
		for(Vehiculo instancia:instancias){
			instancia.mostrar();
			System.out.println("");
		}
	}
}

abstract class Vehiculo{
	String nombre;
	String tipoVehiculo;
	String fuenteEnergia="Motor";
	Double velocidadMaxima;
	Double velocidadActual;
	Double relacionAceleracion;
	int cantidadTripulacion;

	public void mostrar(){
		System.out.println(" Información del vehículo");
		System.out.println(" Nombre ...........: "+nombre);
		System.out.println(" Tipo   ...........: "+tipoVehiculo);
		System.out.println(" Fuente de energía : "+fuenteEnergia);
		System.out.println(" Tripulación ......: "+cantidadTripulacion);
		System.out.println(" Velocidad máxima .: "+velocidadMaxima);
		System.out.println(" Velocidad actual .: "+velocidadActual);
	}
}

class VehiculoTerrestre extends Vehiculo{
	String tipoTerreno;

	public VehiculoTerrestre(){
		tipoVehiculo="Terrestre";
	}

	public void mostrar(){
		super.mostrar();
		System.out.println(" Tipo de terreno ..: "+tipoTerreno);
	}
}

class VehiculoAcuatico extends Vehiculo{
	String tipoNavegacion;

	public VehiculoAcuatico(){
		tipoVehiculo="Acuatico";
	}
}

class VehiculoAereo extends Vehiculo{
	Double alturaMaxima;
	String tipoCarga;

	public VehiculoAereo(){
		tipoVehiculo="Aereo";
	}
}
28
Abr
13

Propiedades de la P.O.O. (Polimorfismo parte 1)

Uno de los beneficios que se obtiene de la programación orientada a objetos es el Polimorfismo. Usando la definición de la RAE se define como: una «Propiedad de las especies de seres vivos cuyos individuos pueden presentar diferentes formas o aspectos«; este principio también es aplicado a la P.O.O.

El principio funciona de una manera básica y es que: diferentes objetos utilicen el mismo protocolo para funcionar de manera diferente, o dicho de otra manera: que cada Objeto responda de manera diferente al invocar el mismo método; la ventaja de esto, es que la clase donde se invoca el método no debe preocuparse de la implementación (de que manera hace lo que tiene que hacer) o el tipo de objeto que es, lo único que tiene en cuenta es que el objeto permita invocar el método especifico.

Utilizaremos el código anterior (P.O.O. Herencia)  para continuar con la explicación y le prestaremos especial atención al método mostrar y acelerar. más documentación sobre interfaces

Interfaces.java
Aquí describimos las interfaces con que vamos a trabajar

package ingenio.ds.examples;

//*definición de la interfaz acelerable*/
interface Mostrable{
	//*definición del método mostrar*/
	public void mostrar();
}

//*definición de la interfaz acelerable*/
interface Acelerable{
	//*definición del método acelerar*/
	public void acelerar(int segundos);
}

Clases.java
Aquí implementamos las interfaces.

package ingenio.ds.examples;

class Vehiculo implements Acelerable,Mostrable{
	String nombre;
	String tipoVehiculo;
	String fuenteEnergia;
	Double velocidadMaxima;
	Double velocidadActual;
	Double relacionAceleracion;
	int cantidadTripulacion;

	/*
	 *Este será el método general utilizado por todos vehículos que no implemen
	 *ten un método acelelar pópio, está es una implementación del metodo descr
	 *ito en la interfaz Acelerable
	 */
	public void acelerar(int segundos){
		System.out.println(" Acelerar vehículo .");
		for(int i=0;i<segundos;i++){ 			velocidadActual=velocidadActual+(velocidadMaxima/2*relacionAceleracion); 			if(velocidadActual>velocidadMaxima){
				velocidadActual=velocidadMaxima;
				break;
			}
		}
	}

	public void mostrar(){
		System.out.println(" Información del vehículo");
		System.out.println(" Nombre ...........: "+nombre);
		System.out.println(" Tipo   ...........: "+tipoVehiculo);
		System.out.println(" Fuente de energía : "+fuenteEnergia);
		System.out.println(" Tripulación ......: "+cantidadTripulacion);
		System.out.println(" Velocidad máxima .: "+velocidadMaxima);
		System.out.println(" Velocidad actual .: "+velocidadActual);
	}
}

class VehiculoAereo extends Vehiculo{
	Double alturaMaxima;
	String tipoCarga;

	public VehiculoAereo(){
		tipoVehiculo="Aereo";
	}

}

class Avion extends VehiculoAereo{
	int cantidadMotores;
	String tipoAvion;

	public Avion(){
		nombre="Avión";
		fuenteEnergia="Motor";
		relacionAceleracion=0.3;
	}

	public void mostrar(){
		super.mostrar();
		System.out.println(" Tipo de avión ....: "+tipoAvion);
		System.out.println(" Cantidad de motore: "+cantidadMotores);
	}

	public void acelerar(int segundos){
		System.out.println(" Acelerar avión ");
		System.out.println(" - Inyecta combustible ");
		System.out.println(" - Gases  ");
		System.out.println(" - Chispa ");
		System.out.println(" - Aumentar presión en la combustión ");
		for(int i=0;i<segundos;i++){ 			System.out.println(" - Aumentar revoluciones en el motor");	 			velocidadActual=velocidadActual+(velocidadMaxima/2*relacionAceleracion); 			if(velocidadActual>velocidadMaxima){
				velocidadActual=velocidadMaxima;
				break;
			}
		}
	}

}

class VehiculoTerrestre extends Vehiculo{
	String tipoTerreno;

	public VehiculoTerrestre(){
		tipoVehiculo="Terrestre";
	}

	public void mostrar(){
		super.mostrar();
		System.out.println(" Tipo de terreno ..: "+tipoTerreno);
	}
}

class Bicicleta extends VehiculoTerrestre{
	String tipoBicicleta;
	int cantidadLlantas;
	String material;

	public Bicicleta(){
		nombre="Bicicleta";
		tipoTerreno="Terreno firme";
		fuenteEnergia="Propulsión humana";
		relacionAceleracion=0.04;
	}

	public void acelerar(int segundos){
		System.out.println(" Acelerar bicicleta ");
		System.out.println(" - Tomar aíre (MUCHO AÍRE) ");
		for(int i=0;i<segundos;i++){ 			System.out.println(" - Aplicar más fuerza sobre el pedal ");	 			System.out.println(" - Aplicar más fuerza sobre el otro pedal"); 			velocidadActual=velocidadActual+(1+relacionAceleracion); 			if(velocidadActual>velocidadMaxima){
				velocidadActual=velocidadMaxima;
				break;
			}
		}
	}
}

class VehiculoAcuatico extends Vehiculo{
	String tipoNavegacion;

	public VehiculoAcuatico(){
		tipoVehiculo="Acuatico";
	}
}

class Submarino extends VehiculoAcuatico{
	String tipoSubmarino;

	public Submarino(){
		nombre="Submarino";
		fuenteEnergia="Propulsión mecánica";
		relacionAceleracion=0.15;
		tipoNavegacion="Bajo superficie";
	}

	public void mostrar(){
		super.mostrar();
		System.out.println(" Tipo de submari ..: "+tipoSubmarino);
	}

	public void acelerar(int segundos){
		System.out.println(" Acelerar submarino ");
		System.out.println(" - Inyecta combustible ");
		System.out.println(" - Gases  ");
		System.out.println(" - Chispa ");
		System.out.println(" - Aumentar presión en la combustión ");
		for(int i=0;i<segundos;i++){ 			System.out.println(" - Aumentar revoluciones en las aspas ");	 			velocidadActual=velocidadActual+relacionAceleracion; 			if(velocidadActual>velocidadMaxima){
				velocidadActual=velocidadMaxima;
				break;
			}
		}
	}
}

Main.java
Aquí dejamos que ocurra la maJia

package ingenio.ds.examples;

public class Main {

   public static void main(String argumentos[]){
		//*Creamos instancias de las sub-clases Bicicleta, Avion, Submarino*/
		Avion v1=new Avion();
		Bicicleta v2=new Bicicleta();
		Submarino v3=new Submarino();

		/*seteamos valores para el Avion*/
		v1.velocidadActual=0.0001;
		v1.velocidadMaxima=850.0;
		v1.cantidadTripulacion=2;
		v1.cantidadMotores=4;
		v1.tipoAvion="Pasajeros";
		v1.alturaMaxima=10400.0;

		//*seteamos valores para la Bicicleta*/
		v2.velocidadActual=1.0;
		v2.velocidadMaxima=60.0;
		v2.cantidadTripulacion=1;
		v2.cantidadLlantas=2;
		v2.material="Aluminio/Fibra";
		v2.tipoBicicleta="Montañera";

		//*seteamos valores para el Submarino*/
		v3.velocidadActual=0.0001;
		v3.velocidadMaxima=460.0;
		v3.cantidadTripulacion=8;
		v3.tipoSubmarino="Militar";

		//*Creamos un arreglo de la super clase y agregamos las instancias de las sub clases*/
		Vehiculo[] vehiculos= new Vehiculo[]{v1,v2,v3};
		acelerar(vehiculos);
	}

	//*recibimos un arreglo de la super clase
	public static void acelerar(Acelerable acelerables[]){
		//*recorremos este arreglo*/
		for(Acelerable acelerable:acelerables){
			//*he invocamos al método mostrar, definido en la interfaz Mostrable
			((Mostrable)acelerable).mostrar();
			//*aceleramos durante 6 segundos
			acelerable.acelerar(6);
			//*mostramos la velocidad final descrita en la clase Vehiculo
			System.out.println(" Velocidad final ..: "+((Vehiculo)acelerable).velocidadActual);
			System.out.println("");
		}
		/*Al método void acelerar(Acelerable[])
		 *en las líneas 47 y 49, no le consierne cuales son los procesos internos q
		 *ue se deben realizar para acelerar un vehículo, ni para mostrar la inform
		 *ación del mismo; lo único que se toma en cuenta es que esté permita invoc
		 *ar dichos métodos.
		 */
	}
}
27
Abr
13

Ingenio DS en Dopbox

Lamentablemente el escritor de Ingenio DS no ha tenido el tiempo de escribir y la editora no ha tenido tiempo de editar, pero a petición de varios de nuestros lectores pasamos los archivos de ejemplos a DropBox;  si encuentran un enlace roto a alguno de nuestros ejemplos avisen por aquí o por facebook o por twitter 2013-04-27_10h44_10

08
Feb
13

Propiedades de la P.O.O. (Interfaces)

Una Clase define la manera la que accedemos a los atributos de las instancias (Objectos) de la misma. Ese conjunto de métodos forman la interfaz del Objeto con el mundo exterior; por ejemplo el switch de una lampara es parte de la interfaz del objeto Lampara con el objeto Persona.

En la descripción más básica una interfaz es un conjunto de métodos con cuerpos vacíos que se relacionan entre sí, no puede tener variables solo se permite la declaración de constantes, y de los métodos solo se puede declarar la firma de este [la firma de un método está compuesta por: tipo de dato de retorno | nombre del método | parámetros de entrada]. De las interfaces no se pueden crear instancias pero se pueden crear implementaciones y éstas implementaciones deben describir el cuerpo del método descrito en la interfaz. A demás a las interfaces también se les aplica el principio de la ‘Herencia’, pero en estas existe la figura de herencia multiple, que no existe en la herencia de clases.

Para el ejemplo de Interfaces que se aplicará al ejemplo usando en el código anterior (P.O.O. Herencia)  para continuar con la explicación.

package ingenio.ds.examples;

public class Interfaces{

	public static void main(String argumentos[]){

	}
	/*
	 *En las implementaciones de Mostrable o Acelerable no nos importa
	 *de que clase son los objetos lo único que tenemos en cuenta es q
	 *ue */
	public static void acelerar(AcelerableMostrable instancias[]){
		for(AcelerableMostrable instancia:instancias){
			instancia.mostrar();
			instancia.acelerar(6);
		}
	}
}

/*definición de la interfaz mostrable*/
interface Mostrable{
	/*definición de una constante, debe ser 'static final' por convención se e
	 *scribre el nombre en mayuscula sostenida*/
	public static final boolean ES_MOSTRABLE=true;
	/*definición del método mostrar*/
	public void mostrar();
}

/*definición de la interfaz acelerable*/
interface Acelerable{
	/*definición de una constante, debe ser 'static final' por convención se e
	 *scribre el nombre en mayuscula sostenida y los espacios con '_' */
	public static final double RELACION_ACELERACION=0.2;
	/*definición del método acelerar*/
	public void acelerar(int segundos);
}

/*dentro de las interfaces también existe la figura de la herencia aunque en e
 *estas puede hacerse de manera multiple*/

interface AcelerableMostrable extends Mostrable,Acelerable{

	/*esta interfaz tiene  por herencia las constantes boolean ES_MOSTRABLE y
	 * double RELACION_ACELERACION */

	/*esta interfaz tiene  por herencia los métodos void mostrar() y void acel
	 *erar(int) */

}

La implementación de una interfaz permite a una clase ser más formal respecto a los atributos y métodos que esta debe proporcionar,  las interfaces forman un contrato entre la clase que las implementan y el resto del mundo, y este contrato es aplicado por el compilador y para ser redundantes en tiempo de compilación. Si una clase implementa una interfaz, se sobre entiende que todos los métodos definidos por esa interfaz están implementados en el código fuente de la clase.

04
Feb
13

Los números de 2012

Los duendes de las estadísticas de WordPress.com prepararon un informe sobre el año 2012 de este blog.

Aquí hay un extracto:

19.000 personas caben en el nuevo Centro de Barclays para ver la actuación de Jay-Z. Este blog fue visto sobre 120.000 veces en 2012. Si fuera un concierto en el Centro de Barclays, tomaría cerca de 6 conciertos con entradas agotadas para ganar estas visitas.

Haz click para ver el reporte completo.

26
Ene
13

Historia de MEGAUPLOAD (infografía)

Un resumen de la historia, presente y futuro de megaupload

CR_789700_mega

22
Nov
12

Enviar email con Java GMAIL/HOTMAIL

Para enviar correos electrónicos en java utilizaremos el API Java Mail, este API proporciona soporte para la construcción y envío de correos, independientemente del protocolo o la plataforma.

para nuestro ejemplo utilizamos 2 plataformas de emails:

  • gmail
  • hotmail

El ejemplo está basado en el patrón MVC tratado anteriormente en esta entrada, y subir archivos al servidor tratado en esta entrada; pero lo realmente importante son 3 archivos los (2) archivos de configuración y (1) la clase MailSender que es la encargada de hacer la magia.

la clase MailSender

package org.ingenio.ds.util.mail;

import org.apache.commons.fileupload.FileItem;

import com.sun.mail.smtp.SMTPTransport;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Properties;
import java.util.StringTokenizer;
import javax.activation.DataHandler;
import javax.activation.DataSource;
import javax.mail.BodyPart;
import javax.mail.Message;
import javax.mail.Multipart;
import javax.mail.Session;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;
import javax.mail.util.ByteArrayDataSource;

public class MailSender{

	public static void enviarCorreo(String tipoServidor,String asunto, String destinatarios, List<FileItem> adjuntos, String contenido) throws Exception {
		if(tipoServidor==null){
			tipoServidor="smtp";
		}
		//objeto donde almacenamos la configuración para conectarnos al servidor
        Properties properties = new Properties();
        //cargamos el archivo de configuracion
        properties.load(new MailSender().getClass().getResourceAsStream("/org/ingenio/ds/util/mail/"+tipoServidor+".properties"));
        //creamos una sesión
        Session session = Session.getInstance(properties, null);
		//creamos el mensaje a enviar
        Message mensaje = new MimeMessage(session);
        //agregamos la dirección que envía el email
        mensaje.setFrom(new InternetAddress(properties.getProperty("mail.from")));
        List<InternetAddress> emailsDestino = new ArrayList<InternetAddress>();
        int i = 0;
        StringTokenizer emailsSt = new StringTokenizer(destinatarios,";,");
        while (emailsSt.hasMoreTokens()) {
        	String email=emailsSt.nextToken();
        	try{
        		//agregamos las direcciones de email que reciben el email, en el primer parametro envíamos el tipo de receptor
        		mensaje.setRecipients(Message.RecipientType.TO, new InternetAddress(email));
        		//Message.RecipientType.TO;  para
        		//Message.RecipientType.CC;  con copia
        		//Message.RecipientType.BCC; con copia oculta
        	}catch(Exception ex){
        		//en caso que el email esté mal formado lanzará una exception y la ignoramos
        	}
        }
        mensaje.setSubject(asunto);
        //agregamos una fecha al email
        mensaje.setSentDate(new Date(1,1,1));
        BodyPart messageBodyPart = new MimeBodyPart();
        messageBodyPart.setText(contenido);
        Multipart multipart = new MimeMultipart();
        multipart.addBodyPart(messageBodyPart);
        if (adjuntos != null) {
            for (FileItem adjunto : adjuntos) {
            	//agregamos los adjuntos
                messageBodyPart = new MimeBodyPart();
                DataSource source = new ByteArrayDataSource(adjunto.getInputStream(), adjunto.getContentType());
                messageBodyPart.setDataHandler(new DataHandler(source));
                messageBodyPart.setFileName(adjunto.getName());
                multipart.addBodyPart(messageBodyPart);
            }
        }
        mensaje.setContent(multipart);
        SMTPTransport transport = (SMTPTransport) session.getTransport("smtp");
        try {
        	//conectar al servidor
            transport.connect(properties.getProperty("mail.user"), properties.getProperty("mail.password"));
            //enviar el mensaje
            transport.sendMessage(mensaje, mensaje.getAllRecipients());
        } finally {
        	//cerrar la conexión
            transport.close();
        }
    }
}

y nuestros 2 archivos de configuración
configuración servidor smtp de gmail
gmail.properties

# archivo de configuración de email de gmail
mail.smtp.host=smtp.gmail.com
mail.smtp.auth=true
mail.smtp.port=587
mail.smtp.starttls.enable=true
mail.from=tucorreo@gmail.com
mail.user=tucorreo@gmail.com
mail.password=tuclave

configuración servidor smtp de hotmail
hotmail.properties

# archivo de configuración de email de hotmail
mail.smtp.host=smtp.live.com
mail.smtp.auth=true
mail.smtp.port=25
mail.smtp.starttls.enable=true
mail.from=tucorreo@hotmail.com
mail.user=tucorreo@hotmail.com
mail.password=tuclave

dentro de los archivos de configuración las líneas

mail.from=tucorreo@hotmail.com
mail.user=tucorreo@hotmail.com
mail.password=tuclave

se utilizan para el envío del email pero no son para la configuración del smtp.

22
Nov
12

Propiedades de la P.O.O. (Herencia)

La herencia en la programación orientada a objetos es la propiedad que nos permite que diferentes clases de objectos tengan ciertas características en común entre ellos. por ejemplo Vehículos, existen varios tipos de vehículos como terrestres, aéreos,  acuáticos y dentro de cada una de estas clases podemos especificaciones de cada una de ella,  por ejemplo terrestres: bicicleta, motocicleta, automóvil; aéreos: aerostato, avión, cohete; acuático: balsa, submarino, buque. pero en todos ellos podemos  encontrar características comunes velocidad actual, velocidad máxima, número de pasajeros, fuente de energía. de igual manera cada uno de ellos define sus propias características que (redundante) lo hacen único de los demás.

ejemplo de herencia

La programación orientada a objetos permite  por medio de  la herencia que una clase tenga atributos y métodos comunes con otra, sin necesidad de realizar una definición explicita de dichas características. en el lenguaje de programación Java se permite heredar de una sola clase, así una clase solo puede tener una super-clase, y a su vez puede tener un número indeterminado de sub-clases.  en el ejemplo  Vehiculo es super-clase de VehiculoTerrestre, VehiculoAcuatico, VehiculoAereo.

public class Herencia{

	public static void main(String argumentos[]){

		//*Creamos instancias de las sub-clases Bicicleta, Avion, Submarino
		Avion v1=new Avion();
		Bicicleta v2=new Bicicleta();
		Submarino v3=new Submarino();

		//*seteamos valores para el Avion
		v1.velocidadActual=0.0001;
		v1.velocidadMaxima=850.0;
		v1.cantidadTripulacion=2;
		v1.cantidadMotores=4;
		v1.tipoAvion="Pasajeros";
		v1.alturaMaxima=10400.0;

		//*seteamos valores para la Bicicleta
		v2.velocidadActual=1.0;
		v2.velocidadMaxima=60.0;
		v2.cantidadTripulacion=1;
		v2.cantidadLlantas=2;
		v2.material="Aluminio/Fibra";
		v2.tipoBicicleta="Montañera";

		//*seteamos valores para el Submarino
		v3.velocidadActual=0.0001;
		v3.velocidadMaxima=460.0;
		v3.cantidadTripulacion=8;
		v3.tipoSubmarino="Militar";

		//*Creamos un arreglo de la super clase y agregamos las instancias de las sub clases
		Vehiculo[] vehiculos= new Vehiculo[]{v1,v2,v3};
		acelerar(vehiculos);
	}

	//*recibimos un arreglo de la super clase
	public static void acelerar(Vehiculo vehiculos[]){
		//*recorremos este arreglo
		for(Vehiculo vehiculo:vehiculos){
			//*he invocamos al método mostrar
			vehiculo.mostrar();
			//*aceleramos durante 6 segundos
			vehiculo.acelerar(6);
			//*mostramos la velocidad final
			System.out.println(" Velocidad final ..: "+vehiculo.velocidadActual);
			System.out.println("");
		}
		/*en las líneas:
		 *vehiculo.mostrar();
		 *vehiculo.acelerar(6);
		 *
		 *en realidad se están invocando los métodos de las sub-clases pero ninguna
		 *de ellas sobre-escribe el método acelerar(int segundos), y la clase Subm-
		 *arino no sobre-escribe el método mostrar; para estos casos la sub-clase
		 *hace referencía al metodo de la clase padre:
		 *
		 *al invocar el método mostrar() del objeto v1 (Avion) se ejecuta el métod-
		 *o sobre escrito en la clase Avion; al inovar el método mostrar() del obj-
		 *eto v2 (instancia de la clase Bicicleta) este invoca el método de la cla-
		 *se padre VehiculoTerrestre; al invocar el metodo mostrar() del objeto v3
		 *en realidad se invoca el método de la clase padre de la clase padre, o s-
		 *ea se invoca el metodo mostrar() de la clase Vehiculo.
		 */
	}

}

class Vehiculo{
	String nombre;
	String tipoVehiculo;
	String fuenteEnergia;
	Double velocidadMaxima;
	Double velocidadActual;
	Double relacionAceleracion;
	int cantidadTripulacion;

	void acelerar(int segundos){
		for(int i=0;i<segundos;i++){
			velocidadActual=velocidadActual+(velocidadMaxima/2*relacionAceleracion);
			if(velocidadActual>velocidadMaxima){
				velocidadActual=velocidadMaxima;
				break;
			}
		}
	}

	void mostrar(){
		System.out.println(" Información del vehículo");
		System.out.println(" Nombre ...........: "+nombre);
		System.out.println(" Tipo   ...........: "+tipoVehiculo);
		System.out.println(" Fuente de energía : "+fuenteEnergia);
		System.out.println(" Tripulación ......: "+cantidadTripulacion);
		System.out.println(" Velocidad máxima .: "+velocidadMaxima);
		System.out.println(" Velocidad actual .: "+velocidadActual);
	}
}

class VehiculoAereo extends Vehiculo{
	Double alturaMaxima;
	String tipoCarga;

	public VehiculoAereo(){
		tipoVehiculo="Aereo";
	}
}

class Avion extends VehiculoAereo{
	int cantidadMotores;
	String tipoAvion;

	public Avion(){
		nombre="Avión";
		fuenteEnergia="Motor";
		relacionAceleracion=0.3;
	}

	void mostrar(){
		super.mostrar();
		System.out.println(" Tipo de avión ....: "+tipoAvion);
		System.out.println(" Cantidad de motore: "+cantidadMotores);
	}
}

class VehiculoTerrestre extends Vehiculo{
	String tipoTerreno;

	public VehiculoTerrestre(){
		tipoVehiculo="Terrestre";
	}

	void mostrar(){
		super.mostrar();
		System.out.println(" Tipo de terreno ..: "+tipoTerreno);
	}
}

class Bicicleta extends VehiculoTerrestre{
	String tipoBicicleta;
	int cantidadLlantas;
	String material;

	public Bicicleta(){
		nombre="Bicicleta";
		tipoTerreno="Terreno firme";
		fuenteEnergia="Propulsión humana";
		relacionAceleracion=0.04;
	}
}

class VehiculoAcuatico extends Vehiculo{
	String tipoNavegacion;

	public VehiculoAcuatico(){
		tipoVehiculo="Acuatico";
	}
}

class Submarino extends VehiculoAcuatico{
	String tipoSubmarino;

	public Submarino(){
		nombre="Submarino";
		fuenteEnergia="Propulsión mecánica";
		relacionAceleracion=0.15;
		tipoNavegacion="Bajo superficie";
	}
}

La sintaxis para decir que una clase es sub-clase de otra es la palabra reservada extends, ClaseHijo extends ClasePadre.

 

11
Abr
12

Hello World desde 1954

10
Abr
12

Programación orientada a objetos

Programación Orientada a Objetos (de ahora en demás P.O.O.), hablar de P.O.O. en estos momentos (del blog) es muy poco ortodoxo, hemos tocado temáticas que tienen como pre-requisitos el manejo de los conceptos de la P.O.O.

Entrando en materia la P.O.O. es un conjunto de técnicas, que se utiliza para el desarrollo de aplicaciones software más eficientes, inclusive mejorando aspectos como la fiabilidad, escalabilidad, mantenimientos, soporte.

Al hablar de P.O.O. no solo nos remitimos a software de usuario ya que también existen sistemas gestores de bases de datos orientados a objetos, sistemas operativos orientados a objetos, interfaces de usuarios orientadas a objetos, etc.

La P.O.O. se basa en cuatro conceptos fundamentales:

  • Clase: descripción de un conjuntos a atributos y funcionalidades.
  • Objeto: instancia de una clase.
  • Herencia: definición de una clase teniendo como base otra.
  • Polimorfismo: que el mismo operador funcione de manera diferente dependiendo el caso.

Nota: estos conceptos serán explicados de manera más concreta en próximas entradas.

Según Grady Booch, la P.O.O. es: «un método de implementación en el que los programas se organizan como colecciones cooperativas de objetos, cada uno representa un instancia de alguna clase, y cuyas clases son todas miembros de una jerarquía de clases unidas mediante relaciones de herencia» [Booch, Grady: Análisis y diseño orientado a objetos con aplicaciones, 2da edición]

De esta definición podemos rescatar tres aspectos importantes:

  • Se utilizan clases no algoritmos ni rutinas.
  • Se referencian clases por medio de instancias llamadas objetos.
  • Las clases se relacionan entre sí, por medio de herencia o composición.

Un aspecto importante que no aparece en la definición de Booch es la comunicación entre objetos:

  • La comunicación entre objetos se da por medio de mensajes o invocaciones de funciones.

Es muy dado a confundir programación con tipos abstractos o programación basa en objetos con programación orientada a objetos; la diferencia más notable entre estos dos paradigmas es la herencia.




I+Ds

Dudas consultas
Facebook
Twiter
Google +

Escribe tu dirección de correo electrónico para suscribirte a este blog, y recibir notificaciones de nuevas publicaciones por correo.

Únete a otros 354 suscriptores

Redes Sociales y Archivos

Entradas

May 2024
L M X J V S D
 12345
6789101112
13141516171819
20212223242526
2728293031