sábado, 28 de junio de 2008

Reflection en Actionscript - Parte 2 - A

Esta es la segunda parte del tutorial sobre reflection. Este esta mas orientado a aplicaciones de la vida real que le podemos dar a reflection. Voy a dividir la parte en dos por lo largo que toman la explicacion de los ejemplos.

Ejemplo 1:

Serializador


Problema:

Se ocupa serializar los objetos de una aplicacion en XML para ser enviados al servidor con sus respectivos valores, nombre de los campos y tipos de los mismos.

No se desean modificar las clases ya construidas.

Solucion:

Para empezar nuestro ejemplo vamos a tomar las siguientes clases de Actionscript. Son tres clases simples describiendo tres abstracciones distintas y sin relacion. Estas clases seran las que tendremos que serializar en un XML. Como no se quieren alterar las clases, se crea una clase utilitaria que se encargara de realizar esta serializacion.

A continuacion la descripcion de las clases:
package serializador.classes
{
public class Perro
{

public var nombre:String;
public var raza:String;
public var peso:Number;
public var color:String;

public function ladrar():void
{
trace("guaw guaw!");
}

}
}
package serializador.classes
{
public class Carro
{

public var marca:String;
public var fabricante:String;
public var anho:Number;
public var motor:Number;

}
}

package serializador.classes
{
public class Persona
{

public var nombre:String;
public var apellidos:String;
public var edad:Number;
public var sexo:String;
public var altura:Number;

}
}

Lo dificil de esta solucion (sin usar reflection) es que se tendria que crear un serializador para cada una de clases (ya que entre ellas no tienen relacion) para poder acceder a cada una de las variables o metodos que se tenga en cada clase (ya que todo esto es desconocido).

Pero con reflection las cosas cambias ya que en tiempo de ejecucion puedo averiguar los metodos, variables y accesors que tiene una clase. Con esto hacemos un metodo que reciba de parametro un objeto y utilizando describeType nos devuelve un XML con la descripcion completa de la clase y lo mejor es que podemos aplicar la solucion a cualquier clase que se quiera sin tener que hacer nada nuevo.

Masomenos algo asi es lo que nos devuelve la funcion describeType:


<type name="Perro" base="Object" isdynamic="false" isfinal="false" isstatic="false">
 <extendsclass type="Object">
<variable name="peso" type="Number">
<method name="ladrar" declaredby="Perro" returntype="void">
<variable name="color" type="String">
<variable name="raza" type="String">
<variable name="nombre" type="String">
</variable>
Esta es la funcion que hacemos:


public static function serialize( item:Object ):XML
{
var descripcion:XML = describeType(item); // invoamos a funcion para describir la funcion. Nos retorna un XML
var root:XML = new XML("<Object type=\""+ descripcion.@name +"\"/>"); //Creamos un nuevo XML que devolveremos posteriormente.

for each (var variable:XML in descripcion.variable){//del XML navegamos por todos los elementos dentro del nodo de Variables

// Creamos un nuevo nodo, su nombre es el de la variable (cargada del XML), el tipo se carga igualmente de la descripcion que encontramos
// en el XML que genera describeType y el valor lo hacemos usando Introspeccion en el objeto pasado por parametro invocando la
// variable por medio de objeto[ variable ]
var node:String = "<property name=\"" + variable.@name + "\" type=\""+ variable.@type + "\">" + item[variable.@name] + "</property>";

root.appendChild(node);//agrega al nuevo XML
}

return root;//retorna nuevo XML con nuestra serializacion
}


Este es el resultado de nuestra funcion pasando de parametro instancias de las clases Carro, Perro y Persona (en ese orden):
<Object type="serializador.classes::Carro">
<property name="fabricante" type="String">Nissan</property>
<property name="marca" type="String">Maxima</property>
<property name="anho" type="Number">2003</property>
<property name="motor" type="Number">1300</property>
</Object>

<Object type="serializador.classes::Perro">
<property name="color" type="String">Cafe</property>
<property name="peso" type="Number">25</property>
<property name="raza" type="String">Bulldog</property>
<property name="nombre" type="String">Bruno</property>
</Object>

<Object type="serializador.classes::Persona">
<property name="altura" type="Number">1.6</property>
<property name="edad" type="Number">38</property>
<property name="apellidos" type="String">Muller</property>
<property name="sexo" type="String">Masculino</property>
<property name="nombre" type="String">Steven</property>
</Object>
Como dije anteriormente la ventaja de esta solucion es que podemos usar cuantos objetos queramos de distintas clases sin tener que alterar nada en nuestra funcion de serializar.

lunes, 23 de junio de 2008

Reflection en Actionscript - Parte 1

Comienzo una serie de dos temas acerca de reflection en Actionscript y Flex.
Cuando hablo de Reflection no me refiero al efecto visual que se genera cuando una imagen o parte de la misma es reflejada en otra area.

El reflection al que me refiero es a la facultad de un programa para que en tiempo de ejecucion pueda examinar su estructura y la de su ambiente y poder modificar lo que hace dependiendo de lo que encuentre. Es una tecnica presente en lenguajes de programacion recientes.

En Java por ejemplo, la funcionalidad de reflection se encuentra dentro del paquete java.lang.reflection, de donde se encuentran toda una serie de clases y metodos para poder examinar la estructura clases y tomar desiciones basados en esa informacion. En Actionscript esta funcionalidad esta basicamente incluida en cuatro funciones que veremos mas adelante.

Debo admitir que el uso de reflection en nuestras aplicaciones no es algo de todos los dias, sin embargo las veces que es utilizada se presenta como una solucion muy elegante para ciertos problemas.

Un poco de mi experiencia personal con reflection:

Mi primer contacto con reflection fue hace como unos 5 a~nos. Ingresaba a laborar en una pequen~a empresa en Miami. No habian muchos empleados aunque si muchos clientes y sobre todo un sistema muy robusto y muy bien disenado que cumplia con todas las necesidades y mas de la empresa. El programador lider era un excelente arquitecto. Tenian un sistema que se conectaba a 6 distintos proveedores - con conectividad e interaccion distinta en cada uno - a traves de un framework inventado en la empresa, que con el uso de interfaces y de reflection lograba en tiempo de ejecucion descargar y cargar las librerias de conectividad e interaccion para los distintos proveedores y realizar la funcionalidad necesaria. Todo era configurado desde un XML y si se necesitaba agregar un nuevo proveedor, se creaba la nueva libreria (.jar en ese caso) y se agregaba en el XML. Reflection hacia toda la magia de la carga de las clases y de encajarlo todo dentro de la aplicacion sin tener que compilarla en ningun momento.

Luego pase a aplicar reflection dentro de aplicaciones Web y de escritorio. Cada vez era mas sencillo utilizar el reflection en las aplicaciones y agregar funcionalidad en tiempo de ejecucion sin tener que compilar mi aplicacion nuevamente. Con la ayuda de un gran libro logre ir aprovechando mejor la herramienta, hasta que migrando de Java a Flex, pude descubrir la funcionalidad que brinda Actionscript y logre anadirla en algunas aplicaciones.

Manos a la obra:

Actionscript provee en el paquete flash.utils una serie de funciones para manejar reflection:

describeType: Recibe un objeto como parametro y devuelve un XML con la descripcion de la clase de la cual es el objeto.

Supongamos que tenemos la siguiente clase:



   1:  package 

   2:  {

   3:      public class Perro

   4:      {

   5:          

   6:          public var nombre:String;

   7:          public var raza:String;

   8:          public var peso:Number;

   9:          public var color:String;

  10:   

  11:          public function ladrar():void

  12:          {

  13:              trace("GUAW GUAW");

  14:          }

  15:   

  16:      }

  17:  }





Aplicamos describe type:

   1:  var bulldog:Perro = new Perro();

   2:  describeType(bulldog)



Salida:




   1:   

   2:  <type name="Perro" base="Object" isdynamic="false" isfinal="false" isstatic="false">

   3:   <extendsclass type="Object">

   4:   <variable name="peso" type="Number">

   5:   <method name="ladrar" declaredby="Perro" returntype="void">

   6:   <variable name="color" type="String">

   7:   <variable name="raza" type="String">

   8:   <variable name="nombre" type="String">

   9:  </variable>



Una vez que tengamos toda la informacion de la clase variables, accessors, metodos, super clase, etc; podremos ser capaces de acceder a la informacion o invocar los metodos que necesitemos.

getDefinitionByName: Recibe un String como parametro con el nombre completo de una clase y devuelve (si existe) un objeto del tipo clase asignada por parametro que puede ser casteada posteriormente como un Class.

Utilizando la misma clase Perro del ejemplo anterior:




   1:  var clazz:Class = getDefinitionByName("Perro") as Class; //Puede ser getDefinitionByName("paquete.de.la.clase.Perro")

   2:  var miPerro:Object = new clazz();



Se crea una clase del tipo pasado en el String de parametro. Pueden ser clases del framework de Flex o de API de Actionscript o customizadas, como este caso. Solo se ocupa que se contenga la ruta completa (incluyendo el paquete)

El unico problema que tiene esto es que:
  • El compilador, para reducir el tamano de los swfs no incluye en el swf final los archivos de clases que no son utilizadas en algun momento desde nuestra aplicacion. Esto quiere decir que si en ningun otro lado de la aplicacion se crea una nueva instancia de la clase Perro, esta no sera incluida dentro del SWF final y el uso de reflection generara error algo como "ReferenceError: Error #1065: Variable is not defined.". Esto le quita un poco la funcionalidad al reflection ya que te limita a clases que esten instanciadas dentro de la aplicacion. Sin embargo vamos a ver en el siguiente post como podemos crear aplicaciones utilizando reflection a las que podremos anadir funcionalidad en tiempo de ejecucion y sin tener que compilar la aplicacion principal.

getQualifiedClassName
: Recibe un objeto como parametro y devuelve un string con el nombre completo de la clase del cual es tipo el objeto.




   1:  var clazz:Class = getDefinitionByName("Perro") as Class; //Puede ser getDefinitionByName("paquete.de.la.clase.Perro")

   2:  var miPerro:Object = new clazz();

   3:   

   4:  trace( "Objeto Creado de tipo: " + getQualifiedClassName(object) );



Salida:

Objeto Creado de tipo: Perro

getQualifiedSuperclassName: Recibe un objeto como parametro y devuelve un string con el nombre completo de la super clase del cual es tipo el objeto.

Es parecido al ejemplo anterior.

Esto es todo por ahora, en el siguiente post presentare dos aplicaciones del mundo real que se le puede dar al reflection desde actionscript, uno un sencillo serializador de clases a XML y el otro una aplicacion que carga desde un XML distintos proveedores en tiempo de ejecucion y que permite anadir nuevos proveedores sin tener que compilar la aplicacion principal.

martes, 20 de mayo de 2008

Problema Integrando Flex y Flash (eventos del mismo tipo con clases distintas)

En el proyecto en que me encuentro laborando actualmente me salio uno de los errores mas raros que he visto.

Sintomas

1. Tenia un componente hecho en flash (swc) incluido en una clase de Flex.
2. El componente en flash despachaba un evento customizado y la clase en Flex no tenia ningun problema con el evento customizado.
3. Cuando interactuaba con el componente que se cerraba o se abria conforme se necesitara, recibia el siguiente evento:

TypeError: Error #1034: Type Coercion failed: cannot convert fl.events::ComponentEvent@dc0f4c1 to mx.events.FlexEvent.
at flash.events::EventDispatcher/dispatchEventFunction()
at flash.events::EventDispatcher/dispatchEvent()
at fl.core::UIComponent/set visible()

El error es que se estaba intentando convertir un evento de tipo fl.core.UIComponent a un evento de tipo FlexEvent. Pero... el evento que teniamos conocimiento que despachaba el componente era de una clase distinta. Ademas revisando el codigo del componente cuando veiamos el error, no se estaba despachando ningun tipo de evento desde el componente.

Despues de revisar muchas veces el codigo, nos dimos cuenta que el problema se daba cuando al componente se le hacia visible=false.
Entonces se nos encendio el bombillo y nos pusimos a revisar la documentacion del ComponentEvent y del FlexEvent .

Problema

Al componente Flash hacer visible=false, se despachaba el evento ComponentEvent.HIDE cuyo tipo es "hide" y si se hacia visible=true despachaba un evento ComponentEvent.SHOW de tipo "show". Coincidentemente la clase FlexEvent tiene los tipos de eventos SHOW de tipo "show" y HIDE de tipo "hide". Como pueden observar tienen el mismo nombre. Pero al mismo tiempo nuestro contenedor en Flex tenia listeners para SHOW y HIDE pero de FlexEvent y al tener el mismo tipo o nombre, esos listeners en el Flex iban a ser invocados. Lo que sucede es que los listeners esperaban eventos de tipo FlexEvent y no de ComponentEvent.

Solucion

Agregue listeners directamente al componente para los eventos ComponentEvent.HIDE y ComponentEvent.SHOW e inmediatamente pare su propagacion (event.stopPropagation) para que no llegaran hasta el Flex, osea el contenedor del componente.

Moraleja

Para aplicaciones que vayan a usar componentes Flash en Flex:

1. Se debe programar a la defensiva.. es decir buscar prevenir cualquier situacion en la que algo del Flash API nos pueda dar conflicto con algo del Flex Framework sea un evento, una clase, etc.
2. Cuando se hagan eventos customizados debemos tratar de diferenciar los tipos de ellos lo mas posible, talvez anadiendo el nombre del paquete donde se encuentran.

En fin.. espero que de alguna forma pueda servirle a alguien..

sábado, 26 de abril de 2008

A Leer!!

Si hay algo que he aprendido estos anos de trabajar en programacion, es la necesidad de estar actualizado. Nada es mas importante para un programador que mantenerse al dia con lo ultimo y si se puede un paso adelante que los demas! Talvez no puedas hacerlo todo pero te dara un mejor panorama para pensar en mejores soluciones.
Ahora con el internet es muy sencillo ingresar a Google y buscar cualquier cosa y asi solucionar el problema X que tengas en un determinado momento. Sin embargo concuerdo con otros, en que es necesario leer un libro que talvez no te pueda resolver un simple problema, pero te va a dar las bases, te ayudara a profundizar y te permitara conocer mas la teoria.
Gracias a Dios mi esposa en este aspecto de comprar libros, siempre me ha apoyado al inviertir en libros y si, digo invertir porque es literalmente eso, invertir en la carrera profesional de uno para tener mejores opciones y mayor calidad de trabajo.
En lo personal leer desde una computadora me cansa mucho asi que lo que prefiero es tener el libro y poder llevarlo donde quiera.. rallarlo.. marcarlo.. subrayarlo.. ponerle notas. Eso me sirve - en lo personal - mas que tener un simple PDF y marcarlo ahi.
Por ahora presento un resumen de lo ultimos libros que he comprado y he estado leyendo, talvez alguno le pueda ser de provecho:



Joel on Software:
Uno de mis favoritos... nunca me habia divertido tanto leyendo un libro de tecnologia. Joel es un famoso programador y bloguero que en este libro toca muchos temas picantes en general sobre el mundo de la programacion y su conexion con lo corporativo. Formas de documentar, formas de hacer pruebas, como hacer mejor software (no importando el lenguaje), como ser mejor profesional, etc.. en un formato agradable y divertido y con un autor que SABE LO QUE DICE.
Un libro que me gustaria tener el dinero para comprarlo a todos mis companeros de trabajo.


Rich Internet Applications with Adobe Flex & Java (Secrets of the Masters)

Este libro lo consegui el ano pasado en la conferencia de AJAX en NY. Es hecho por 3 de los programadores de Java/Flex con los que recibi un curso de Flex y que al mismo tiempo respeto. Un enfoque distinto entrando mas hacia el Flex desde el lado empresarial que del lado de diseno. Este libro es caro pero es de los mejores que he comprado. La verdad si pudiera recomendar un libro para programadores de Java entrando a Flex no dudaria en decir que este seria lo mejor que podrian conseguir. En lo personal fue el que me termino de empujar en este mundo.



Advanced ActionScript 3 with Design Patterns

Este libro es pequeno. Solo con eso te sube la moral para seguir leyendolo. Los primeros capitulos no son tan interesantes pero luego se convierte en un libro que TIENE que ser leido por cualquier programador que quiera tomar el AS3 en serio. El mes anterior lo lei casi 3 veces. Es impresionate. Cada vez que se lee se pueden aprender cosas nuevas. El material es para programadores avanzados especialmente si vienes de lenguajes Orientados a Objetos.




Essential ActionScript 3.0
Excelente libro para el que quiera ingresar al mundo de ActionScript 3.0. Es bastante grande y al inicio puede ser un poco decepcionante ver tantas paginas pero poco a poco se le va sacando el jugo a tan excelente libro. Tiene muchos secretos y detalles que no se encuentran en cualquier lugar.

martes, 15 de abril de 2008

Diagramas de Secuencia Faciles

Algunas veces cuando desarrollamos aplicaciones que utilizan otros componentes o interactuan con otros servicios sean externos o internos, el diagrama de secuencia se convierte muy util para poder detallar y explicar el flujo y proceso que se debera seguir.
Talvez no todos tengamos el conocimiento detallado de como hacerlo ni el tiempo ni las herramientas para hacerlo, pero encontre este sitio practico y util para crear de una manera sencilla y practica estos diagramas de secuencia de forma gratuita. Pruebenlo.. esta muy practico y util y muchas veces podra salvarle a uno muchas horas tratando de explicar algo a uno mismo o a otra persona.... http://www.websequencediagrams.com/

martes, 11 de marzo de 2008

Data Binding

Update (2009-03-28): Una entrada mas reciente con un ejemplo

El data binding es una de las caracteristicas mas agradables que provee Flex.

Que es en realidad?

Es un mecanismo que permite que componentes y/o objetos escuchen a los cambios que ocurran en otra variable, objeto o funcion X.

Que permite?

Bueno, permite actualizar informacion en un objeto que escucha (y mostrar esa actualizacion si es necesario) en el momento en que una variable, objeto o funcion que es escuchada cambia su estado (osea alguna propiedad).

Como funciona?

La forma mas elemental ocupa de lo que se llaman Metadata, que es una sentencia especial reconocida por el compilador, que lo que hace es avisarle como debe tratar una cierta sentencia que sigue despues del tag. En el caso de binding se utiliza [Bindable] antes de una variable que se quiera 'bindear'. Los componentes en MXML bindean muchas de sus propiedades principales por default. Una vez que indicamos que una variable va ser bindeada, osea que otros objetos pueden llegar a escuchar cambios que se realicen en ella, procedemos a definir sus escuchas (que pueden ser cero, uno o muchos) Para reflejar esos cambios en MXML, se utiliza '{ variable_bindeada } '. En actionscript puro (no MXML) se usa otro tipo de forma como por ejemplo la clase BindingUtils que provee el framework de Flex.

Que es lo que pasa en realidad?

En realidad lo que es el binding en flex, es el patron Observer simplificado por el uso de Metadata [Bindable] y de { } o BindingUtils
El observer pattern indica una relacion entre dos objetos, en la cual uno notifica al otro u otros acerca de un cambio en su estado y los actualiza automaticamente.
Entonces explicando la teoria, el observador es la variable u objeto que definimos como Bindable

Ejemplos:

Base:

<Application>
<mx:TextInput id="texto1" x="50" y="20"/>
<mx:Label id="etiqueta1" x="50" y="40"/>
</Application>

MXML:
1. Reemplazo del Label:

<mx:Label id="etiqueta1" x="50" y="40" text="{texto1.text}"/>

2. Etiqueta mx:Binding

<mx:Binding source="ObjetoFuente.propiedadEscuchar" destination="ObjetoDestino.propiedad_actualizar" />

en este caso

<mx:Binding source="texto1.text" destination="etiqueta1.text" />

Actionscript:

 BindingUtils.bindProperty(ObjetoDestino, "propiedad_actualizar", ObjetoFuente, "propiedad_escuchar");

Ejm:
BindingUtils.bindProperty(etiqueta1, "text", texto1, "text");


Notas:

Aunque el codigo se vea tan sencillo, detras de todo esto de binding ocurren una gran cantidad de cosas que nosotros no vemos. El uso de binding genera muchisimos archivos y clases mas de lo que vemos y pueden ser vistas si compilamos la aplicacion con la opcion --keep-generated-actionscript que mantiene todos los archivos generados por el compilador que son abreviados por metadatas por ejemplo. Esto se genera debido a que se crean listeners y handlers de esos listeners para cada propiedad bindeada.

jueves, 6 de marzo de 2008

Seminario de Flex y Campamento... y lo mejor... GRATIS!!!

Alguna vez han sentido que han llegado a la cuspide de su carrera profesional? Ha llegado al tope de su conocimiento?? Si es asi... usted esta en problemas! Si usted piensa que ya ha alcanzado todo solo por tener un titulo colgado en una pared o por tener un buen trabajo.. pienselo dos veces... siempre hay algo mejor afuera para usted! Y no lo digo por la simple ambicion de tener mas.. lo digo por el hecho de querer ser mejor en toda area y no un simple conformista. Cual es su valor profesional en el mercado laboral? Es solo su titulo? Es solo un lenguaje lo que le da valor a usted? Entre mas cosas pueda anadirle a su curriculum pero mas importante a su cerebro y a su capacidad, mas oportunidades tendra de seguir avanzando profesionalmente.
Es por eso, que tal como habia dicho en un post anterior, la empresa donde trabajo actualmente esta preparando un evento de Flex para el publico en general.
En realidad son dos distintos, pero dentro de uno mismo :D

Lo primero, un seminario de 5 noches seguidas que empezara el 10 de marzo y terminara el 14 de Marzo. Todas las noches de 7 pm a 9 pm, en el auditorio de la Ulatina (que amablemente esta prestando sus instalaciones) y mencione que era GRATIS???? Gratis? Si.. gratis pero no como cuando te ofrecen una muestra gratis de un producto.. es GRATIS-GRATIS... El segundo es el 15 de Marzo, de 10 am a 3 pm. Gratis tambien.
El seminario seran 5 charlas teoricas y algo de practica con los fundamentos necesarios para aprender Flex...a distribuirse mas o menos asi:


Lunes:
Que es Flex?
Martes:
Componentes de Flex y ActionScript
Miercoles:
Manipulacion de Informacion
Jueves:
Eventos y Drag-n-Drop
Viernes:
Tópicos avanzados

Para Inscribirse aqui
Mas informacion aqui

El Camp Flex, es el evento principal a mi gusto.. en este esperamos que se llene el auditorio. Hicimos la solicitud a Adobe y muy amablemente estaran enviando un 'Evangelista' de ellos mismos para venir y dar una charla a todo el que quiera llegar... Mike Downey nos estara acompanando... Mike es uno de los principales propulsores de AIR, de Adobe. Una herramienta que permitira a los programadores de Flex o de Ajax crear aplicaciones para escritorio con todas las de la ley... solamente asistan al evento y podran ver TODO lo que podran hacer con esto. De verdad es algo increible!!! Tambien segun se me ha dicho nos presentara un demo de Thermo de 12 minutos... Que es Thermo?? Es a mi gusto una de las mejores herramientas que tendra adobe en unos meses que permitira la integracion del disenador grafico y del programador en flex en muy pocos minutos de una manera ASOMBROSA...!! Venga!! Compruebelo usted mismo.

Asi que ya no tiene excusa, si quiere crecer como profesional, si quiere tener mas valor en el mercado laboral, si quiere conocer mas, si quiere hacer algo mas productivo que ver tele y comer en el sillon despues del trabajo, algo mas productivo que despertarse a las 11 de la manana el sabado, acompanenos esta semana que viene, recuerde del 10 de Marzo al 14 de 7 a 9 pm. El 15 de marzo el evento con Mike Downey, de 10 am a 3pm....
Por cierto, mencione que todo es gratis???

Para Inscribirse aqui
Mas informacion aqui