Archive for the ‘análisis’ Category

0 28
11
2010

Reflexión: la gran desconocida en la programación

Domingo, noviembre 28th, 2010

“En informática, reflexión (o reflexión computacional) es la capacidad que tiene un programa de ordenador para observar y opcionalmente modificar su estructura de alto nivel.”

Esta es la definición que aparece en wikipedia en referencia al concepto de reflexión en el mundo de la informática y la programación.

Es una definición un tanto abstracta, pero que nos permite intuir en qué consiste todo esto de la reflexión.

Siendo más concretos y prácticos, el uso de la reflexión a nivel de programación, nos permitirá, entre muchas otras cosas, crear instancias u objetos de dinámicamente de tipos concretos a partir del nombre de su clase. Podremos además, acceder a la información de los objetos, conociendo y/o ejecutando sus atributos y métodos públicos; y todo ello en tiempo de ejecución.

Vamos a plantear un pequeño ejemplo práctico de introducción al uso de reflexión en el lenguaje de programación Java.

Imaginemos la siguiente estructura de clases definida en el diagrama UML que se muestra a continuación.

Diagrama UML Reflexión

Reflexión en Java

Definiremos en primer lugar una clase abstracta denominada Vehicle. Esta clase padre define 2 métodos abstractos (acelerar/speedUp y frenar/brake) que deberán ser implementados por todas aquellas clases hijas que deseen heredar de Vehicle.

Clase (padre) Vehicle

package es.v3.test.reflection;

/**
 * Clase abstracta padre
 * @author v3rgu1.com
 */
public abstract class Vehicle {

    public String name;

    public abstract void speedUp();

    public abstract void brake();

}//Vehicle

A continuación crearemos 2 clases hijas que implementarán la clase abstracta padre Vehicle

Clase (hija) Car


package es.v3.test.reflection;

/**
 * Clase hija que hereda de Vehicle y representa un vehículo de tipo coche.
 * @author v3rgu1.com
 */
public class Car extends Vehicle {

    @Override
    public void speedUp() {
        System.out.println("Me llamo " + this.name + " y soy un coche que está acelerando");
    }

    @Override
    public void brake() {
        System.out.println("Me llamo " + this.name + " y soy un coche que está frenando");
    }

}//Car

Clase (hija) Motorcycle


package es.v3.test.reflection;

/**
 * Clase hija que hereda de Vehicle y representa un vehículo de tipo motocicleta.
 * @author v3rgu1.com
 */
public class Motorcycle extends Vehicle {

    @Override
    public void speedUp() {
        System.out.println("Me llamo " + this.name + " y soy una moto que está acelerando");
    }

    @Override
    public void brake() {
        System.out.println("Me llamo " + this.name + " y soy una moto que está frenando");
    }

}//Motorcycle

Una vez creadas estas 3 clases con las que llevaremos a cabo nuestros próximos ejemplos relacionados con la reflexión en programación, vamos a crear una clase ejecutable (main) con la que crearemos instancias en tiempo de ejecución de las clases hijas definidas anteriormente. Recuperaremos además la información de cada una de ellas y ejecutaremos sus métodos públicos sin previo conocimiento de ellos.

Pasaremos 2 argumentos a nuestra clase ejecutable por línea de comandos: el nombre de la clase a instanciar (“Car” o “Motorcycle”) y el nombre de nuestro vehículo.
Vamos a crear una instancia en tiempo de ejecución del tipo indicado en el primer argumento, para utilizar después sus métodos implementados speedUp & brake.

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {

        String nameClass = args[0];
        String nameVehicle = args[1];
        try {
            Class vehicleClass = Class.forName("es.v3.test.reflection." + nameClass);
            Field[] fields = vehicleClass.getFields();
            Method[] methods = vehicleClass.getDeclaredMethods();
            try {
                Vehicle vehicle = (Vehicle) vehicleClass.newInstance();
                vehicle.name = nameVehicle;
                vehicle.speedUp();
                vehicle.speedUp();
                vehicle.brake();
                for (int i=0; i<fields.length; i++) {
                    Field field = fields[i];
                    System.out.println("Campo '" + field.getName() + "': " + field.get(vehicle));
                }//for i
                for (int i=0; i<methods.length; i++) {
                    Method method = methods[i];
                    System.out.println("Voy ejecutar el método: '" + method.getName() + "'");
                    method.invoke(vehicle);
                }//for i
            } catch (IllegalArgumentException ex) {
                Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
            } catch (InvocationTargetException ex) {
                Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
            } catch (InstantiationException ex) {
                Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
            } catch (IllegalAccessException ex) {
                Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
            }
        } catch (ClassNotFoundException ex) {
            Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
        }

    }//main

Con la ayuda del API reflect de Java, hemos instanciado una clase sin conocer a priori el tipo de la misma y únicamente a partir de su nombre, pero veamos más en detalle las funciones utilizadas en el ejemplo.

java.lang.Class forName(String className) javadoc
Devuelve el objeto Class asociado a la clase o interface indicada en el nombre que recibe por parámetro.

java.lang.Object newInstance() javadoc
Crea una nueva instancia del objeto representado por la clase actual.

java.lang.reflect.Field[] getFields() javadoc
Retorna un array con todos los atributos con acceso público de la clase o interfaz representada.

java.lang.reflect.Method[] getMethods() javadoc
Devuelve un array que contiene todos los métodos públicos de la clase o interfaz representada.

java.lang.reflect.Method[] getDeclaredMethods() javadoc
Devuelve un array que contiene todos los métodos declarados en la clase o interfaz representada.

En próximo artículos, veremos cómo realizar este mismo ejemplo de reflexión en otros lenguajes de programación, así como el uso técnicas de reflexión más avanzadas.

0 12
10
2010

Crea diagramas UML online con yUML

Martes, octubre 12th, 2010

Navegando por la red, y de casualidad (como la mayoría de los grandes descubrimientos), encontré yUML.

yUML es una aplicación web que nos permite crear diagramas UML totalmente on-line y de una forma rápida y sencilla.

yUML: create UML diagrams online

Lejos de las típicas pesadas aplicaciones de escritorio que solemos utilizar a la hora de crear un diagrama UML, podremos generar con yUML diagramas sencillos (y agradables a la vista) en pocos minutos; y lo que es mejor y más importante, es una herramienta gratuita y no requiere ningún tipo de registro.

Al tratarse por lo tanto de una herramienta online, podemos a partir de ahora compartir nuestros diagramas en blogs, foros, emails, wikis, etc con un simple enlace de imagen, que como veremoa a continuación, incorpora el código del diagrama.

Lejos además también de los entornos gráficos del estilo drag & drop con los que solemos trabajar, yUML trabaja con un entorno de texto en el que indicaremos cada acción o relación existente en el diagrama UML.

A día de hoy, la herramienta yUML nos permite crear hasta 3 tipos de diagramas UML (que normalmente son los más utilizados):

La idea es sencilla, veámoslo con un ejemplo de diagrama de clases UML.

Conceptos básicos:

  • – las clases se identifican entre corchetes [].
  • – el orden de la relación con flechas ->
  • – la cardinalidad con números y asteriscos *
  • – los colores de fondo con la indicación: {bg: coloreninglés}, ejemplo: {bg: orange}

Aquí os dejo un diagrama de clases muy sencillo generado a partir el siguiente código:

# Travel UML Diagram
[Transport]^-[Train]
[Transport]^-[Flight]
[Transport]^-[Bus]

y su resultado final

diagramas UML online con yUML

Para los curiosos, fijaros en la URL de la imagen:

<img class="aligncenter" src="http://yuml.me/diagram/scruffy/class/%23%20Cool%20UML%20Diagram,%20%5BTransport%5D%5E-%5BTrain%5D,%20%5BTransport%5D%5E-%5BFlight%5D,%20%5BTransport%5D%5E-%5BBus%5D" alt="uml class diagram" width="323" height="235" />

Efectivamente, el código que habíamos creado inicialmente se incrusta dentro del html para poder generar nuestro diagrama final.