Mostrando entradas con la etiqueta Flex. Mostrar todas las entradas
Mostrando entradas con la etiqueta Flex. Mostrar todas las entradas

domingo, 6 de diciembre de 2009

Patron Proxy en Flash

Recientemente me encontraba trabajando con Shared Objects (SO) en Flex para persistir ciertas propiedades en el cliente y empece a ver mas frecuentemente el uso de este codigo:


var settings:SharedObject = SharedObject().getLocal("/settings");

try
{
settings.data["property"] = value;
settings.flush();
}catch(e:Error)
{
...
}


Inmediatamente decidi mover esto dentro de una clase donde tenia un SharedObject y desde donde simplemente invocaba un metodo y le pasaba 2 parametros, uno con el key y otro con el value para el key, terminando con algo asi:


public function put(key:String, value:*):void
{
try
{
_sharedObject.data[key] = value;
_sharedObject.flush();
}
catch(e:Error)
{
log.error("Error while persisting setting. " + e);
}
}


Ya mi codigo empezo a verse con mucho menos lineas de codigo y tenia una clase reutilizable para interactuar con SO:

Definia esto al inicio de mi clase indicando cual shared object queria usar
var settings:SharedObjectWrapper = new SharedObjectWrapper(SharedObject().getLocal("/settings"));

Invocaba a mi clase asi:
settings.put("property", value);

Sin embargo, queria hacer algo todavia mas sencillo, mas que por funcionalidad por majaderia :) y me acorde de la clase Proxy que trae el Flash API.

Que es?

La clase Proxy que viene en el paquete flash.utils, es una clase "abstracta"(aunque no es verdad pues AS3 no permite esas clases), que quiere decir que sus metodos que usemos deben ser definidos a la hora de extender la clase y ademas no puede ser instanciada. Esta clase viene a reemplazar a Object.__resolve y Object.addPropert en AS2.

El Proxy nos permite agregar comportamiento a otras clases por medio de la definicion de ciertos metodos. Estos metodos se encargan de "escuchar" los llamados a las propiedades y servicios (funciones) en un objeto y responder a esos llamados para redireccionarlos dentro de la clase (como veremos mas abajo)

Algunos de los metodos principales definidos en la clase Proxy son:

callProperty(name:*, ... rest):*

Escucha el llamado de una funcion, los parametros son:
name -> nombre de la funcion
rest -> un Array de parametros

y retorna un valor de cualquier tipo

getProperty(name:*):*

Escucha el llamado a una propiedad de un objeto
name -> nombre de la propiedad
y retorna un valor de cualquier tipo

setProperty(name:*, value:*):void

Escucha el llamado a una propiedad de un objeto a la que se le quiera asignar un valor
name -> nombre de la propiedad
value -> valor a setear, de cualquier tipo

Que quiere decir?

Que extendiendo esta clase y algunos de los metodos definidos podemos hacer que nuestras clases que ya existan puedan tener un comportamiento adicional al que ya tenian, sobre todo si son clases hechas por otras personas o que no podamos modficar.
Vamos a ver un ejemplo, digamos que ocupamos tener un objeto dentro de nuestra clase en el cual guardaremos propiedades como un Hash. Esto lo podemos hacer facilmente haciendo esto:


var hash:Object = new Object();

hash['prop'] = value;

trace(hash.prop);


Sin embargo nuestros requerimientos nos indican que debemos logguear un mensaje indicando que propiedad esta seindo invocada y a que hora. Ahora el ejemplo talvez no tenga mucho sentido, pero sigan leyendo...

Si hicieramos esto con el codigo anterior tendriamos que poner codigo adelante de nuestros llamados (o detras) con la informacion logueada. Tambien podriamos hacer una clase que se encargue de encerrar esa logica de logguear y asignar data en un metodo, o podemos usar el Proxy:


//Primero importemos el namespace flash_proxy que es necesario para hacer override de los metodos de la clase Proxy
import flash.utils.Proxy;
import flash.utils.flash_proxy;

use namespace flash_proxy;

public class class MyProxy extends Proxy {

private var data:Object = new Object();// Este objeto contendra nuestra informacion

//Retorna undefined si la propiedad no existe
override flash_proxy function getProperty(name:*):*
{
trace("Invocando propiedad: " + name);
return data[name];
}

override flash_proxy function setProperty(name:*, value:*):void
{
trace("Agregando propiedad: " + name + " con valor " + value);
data[name] = value;
}

override flash_proxy function callProperty(name:*, ... rest):*
{
//Aqui podemos llamar a otros metodos en esta clase o de otro objeto
//que tengamos referencia dentro de la misma
if(name == "iterate")
{
trace("Contenido del objeto: ");
for each(var val:* in data) {
trace(val);
}
}
}
}


El metodo getProperty es invocado cada vez que alguna instancia de la clase MyProxy le sea invocada una propiedad, algo asi:


var proxy:MyProxy = new MyProxy();

trace(proxy.color);//Getproperty es invocado


El metodo setProperty es invocado cada vez que se setea una propiedad de la instancia:


proxy.color = "verde";//SetProperty es invocado


Y finalmente el metodo callProperty es invocado cuando hacemos esto:


proxy.iterate;


Como pueden ver no se tiene que llamar a proxy.getProperty("color") o proxy.setProperty("color", "verde") o proxy.callProperty("iterate"), sino directamente a las propiedades o nombres de metodos que queremos tener. y el FP se encarga de invocar esos metodos en tiempo de ejecucion. El se encarga de hacer la logica necesaria y la magia la ejecuta el flash player que reconoce cual metodo invocar (getProperty, setProperty, callProperty o el que sea).

Esto es super util como mencione arriba para agregar comportamiento a clases que ya existen, pensando en un AOP mucho mucho mas sencillo pero igualmente efectivo.

Pues finalmente lo que hice con mi SharedObject fue poner un comportamiento parecido al de arriba y entonces logre tratar mi interaccion con el shared object que inicialmente necesitaba al menos 5 lineas, que despues baje a la invocacion de solo un metodo a poder hacer algo como esto:


settings.property = value; //dentro de este llamado esta el try/catch y el flush del SO.


Teoria:

Esto que acabamos de ver es el patron de dise~no Proxy, que como lo indica su nombre es una objeto que toma el lugar de otro. Este patron es usado a traves del Flash Api y Flex Framework en multiples lugares como el Loader donde tenemos acceso a propiedades (width, height) aunque no tengamos acceso al contenido al mismo instante. Tambien el RemoteObject en Flex hace uso de este patron cuando invocamos operaciones directamente del remote Object, por ejemplo: ro_user.loginUser(username,password); en este caso se llama remote proxy, pero es basicamente la misma idea solo que accedemos a datos remotos o externos.

La usabilidad de este patron es bastante amplia y muchas veces es muy despreciado, pero he de admitir que es una solucion muy elegante y sencilla para muchos problemas, ademas que el Flash API nos provee las herramientas necesarias para hacer este tipo de cosas de una manera muy sencilla.

lunes, 16 de noviembre de 2009

Pseudo Threads en Actionscript

Como mencione en un post anterior el Flash Player aunque internamente tiene un sistema de Threads o hilos que permite ejecutar multiples tareas al mismo tiempo, no provee a nosotros los desarrolladores la funcionalidad para utilizar threads nativamente. Esto hace por supuesto que aplicaciones nuestras donde se procesen muchos datos o con funciones o procesamiento muy pesado haga que nuestras aplicacion se congele o se pegue...
Como desarrolladores no tenemos otra forma de hacer que esto funcion sino es emulando la funcionalidad de los threads. Digo emulando porque no hay forma de hacerlo nativamente y se hace dividiendo el proceso pesado en multiples pedazos.
Acerca de esto se ha escrito en multiples lugares con contenido muy completo y excelentes soluciones a distintos niveles de complejidad.
Las librerias anteriores y muchas otras lo que hacen es partir el proceso grande en multiples pedazos que seran ejecutados en momentos distintos. Esto disminuye la carga de trabajo y hace que el proceso no se ejecute de un solo sin permitir al FP refrescarse y por lo tanto pegarse.
Sin embargo de las librerias anteriores, mi favorita es la de Grant Skinner, se llama "Chunker" pues parte los procesos en pedazos. Sin embargo basado en esa clase, decidi hacer unas modificaciones que aqui presento:


package com.grayscale.util.threads
{
import flash.display.Shape;
import flash.events.Event;
import flash.events.EventDispatcher;
import flash.utils.getTimer;

/**
* Evento despachado cuando se concluye el proceso.
*/
[Event (type="flash.events.Event", name="complete")]

/**
* Esta clase es una implementacion simple de un pseudo thread en AS3.
*

Esta basada en la clase de Grant Skinner aunque con algunas modificaciones.
* http://www.gskinner.com/libraries/Chunker.zip


*/
public class SimpleThread extends EventDispatcher
{
//Nos permite tener acceso al evento ENTER_FRAME que sera el que lleve el
//paso de cada cuando se ejecutaran nuestros procesos.
private var shape:Shape = new Shape();
//Estado del hilo
private var _paused:Boolean = false;
//Cada cuanto se ejecutara
private var _execTime:uint;
//Funcion a ejecutar
private var _func:Function;
//Argumentos a nuestra funcion. Es un array de elementos que pasariamos a nuestra funcion
private var _args:Array;

/**
* Constructor.
*
* @param execTime Cada cuanto se ejecutara nuestra funcion
* @param func funcion a ejecutar
* @param args parametro opcional con los valores a pasarse en la funcion
*/
public function SimpleThread(execTime:int, func:Function, args:Array=null)
{
_execTime = execTime;
_func = func;
_args = args;

pause = false;
}

/**
* Para el thread o lo arranca
*/
public function set pause(value:Boolean):void
{
_paused = value;
if(_paused) shape.removeEventListener(Event.ENTER_FRAME, run);
else shape.addEventListener(Event.ENTER_FRAME, run);
}


/**
* Metodo que ejecuta nuestra funcion
*/
private function run(event:Event):void
{
var initialTime:int = getTimer();//registra el tiempo donde inicia este iteracion
while(!_paused && (getTimer() < _execTime+initialTime ))//revisa si no hemos excedido la cantidad de tiempo del inicio
{
//llama nuestra funcion y esta tiene que regresar un valor booleano. Si este es falso detiene el thread sino continua.
var res:Boolean = _func.apply(this, _args) as Boolean
if(!res)//ya se termina de ejecutar nuestra funcion, pausamos el thread y despachamos evento avisando que se concluyo
{
dispatchEvent(new Event(Event.COMPLETE));
pause = true;
}
}
}
}
}


El unico requisito para esta clase, es que la funcion que queremos partir debe devolver un valor booleano: true si todavia hay data que procesar, false si ya termino de procesar la informacion.
A continuacion presento dos ejemplos, ambos cargan el mismo archivo(analytics de este blog); uno lo hace sin los pseudo-threads y otro con el pseudo-thread. Podran ver la diferencia como uno se pega y el otro no. Es un archivo grande (4mb) asi que tengan paciencia. Apenas se carga se activa el boton de "Start"
Notas: 1. Debe aparecer un spinner cuando se aprieta el boton de "start". 2. los controles de la pantalla deben ser accesbles mientras se procesan los datos.

Sin Thread.









Con Thread.







Al partir nuestra funcionalidad en multiples ejecuciones y no solo en una, ocupamos una forma de llegar a saber donde terminamos de procesar y desde donde debemos empezar. Para esto puedo sugerir el uso del patron Iterator. Este patron permite a una coleccion encapsular la manera en que se recorre la coleccion y guardar dentro de si misma cual fue el ultimo elemento procesado, sin tener que tener mantener un indice de la coleccion por fuera. El iterador se encarga de todo. Esto es bueno ya que al partir nuestro proceso ocupamos mantener una referencia al dato que estamos procesando sin tener que crear otras variables.
Aqui presento las siguientes clases para tener nuestro iterator.

Interfaz Base:


package com.grayscale.util.iterator
{
/**
* Esta interfaz define los metodos basicos que debera contener un iterador en nuestra coleccion
* @author Ivan Ramirez - ivan.ramirez@gmail.com
*/
public interface IIterator
{
/**
* Devuelve "true" si tenemos mas valores que recorrer dentro de nuestra coleccion
*/
function hasNext():Boolean;
/**
* Devuelve el proximo valor en nuestro iterador
* @returns el siguiente objeto en la coleccion.
*/
function next():*;
/**
* Nos permite reiniciar el recorrido de nuestra coleccion
*/
function reset():void;
}
}


Implementacion basica:


package com.grayscale.util.iterator
{
/**
* Implementacion basica de nuestro iterator para el manejo de arrays. Podemos implementar esta interfaz
* en otras clases para hacer iteradores con Strings o de XML, etc.
* @author Ivan Ramirez - ivan.ramirez@gmail.com
*/
public class ArrayIterator implements IIterator
{
//Coleccion base
private var collection:Array = new Array();
private var index:int;

public function ArrayIterator(values:Array)
{
collection = values
}

public function hasNext():Boolean
{
return index < collection.length;
}

public function next():*
{
return collection[index++];
}

public function reset():void
{
index = 0;
}

}
}


La ventaja de tener una interfaz definiendo el iterador, es que podemos crear nuestras propias implementaciones del iterador de acuerdo a nuestras necesidades.
Ya con nuestro iterador cargado con la coleccion de datos que tenemos que procesar, procedemos a utilizar nuestro thread.

El codigo de las aplicaciones de este ejemplo esta aqui.

domingo, 15 de noviembre de 2009

Como actualiza la pantalla el Flash Player...

El Flash Player(FP) es la maquina virtual que nos permite ejecutar nuestras aplicaciones hechas en Flash, Flex o Actionscript Puro (incluso ejecuta codigo en otros lenguajes cuyo bytecode es "traducido" a un lenguaje que el player entienda, pero eso es para otro post)
Una de los principales usos que se hacen del FP es la parte grafica que ha provisto por muchisimo tiempo excelentes herramientas para desarrolladores y dise~nadores para crear contenido totalmente fuera de lo normal. De hecho podriamos pensar que lo que ha hecho grande y famoso a la plataforma flash es la capacidad de crear aplicaciones que brindan al usuario excelentes experiencias.
Pero... esas excelentes ideas y deseos de buenas experiencias pueden verse truncados si nuestras aplicaciones no estan haciendo uso correcto del FP, sobre todo en la forma en que este maneja la actualizacion de la pantalla.

Ejecucion:

* Definicion: Frame Rate: es la cantidad maxima de veces que por segundo el FP revisara si hay cambios en nuestra aplicacion que se tengan que dibujar en la pantalla. Esto no significa que si tenemos un framerate de 24 fps(frames per second) es que el FP vaya a revisar si hay cambios, 24 veces en un segundo. Esto quiere decir solamente que si todo sale bien, si nada del codigo que uno como desarrollador escribio demora mucho tiempo, el intentara revisar esa cantidad de veces, pero a veces no sera posible.

- Nuestra aplicacion es cargada dentro del FP y es agregada al stage.
- FP ejecuta el codigo inicial de nuestro Frame.
- FP ejecuta algun event listener que sea despachado.
- FP ejecuta el proceso de rendereo (o actualizacion de la pantalla), que basicamente revisa si el codigo ejecutado previamente realizo algun cambio en la parte grafica que deba ser dibujado en la pantalla. Cuando se hace ese chequeo se despacha el evento Event.ENTER_FRAME.
- Si hay cambios, actualiza la pantalla.
- FP espera hasta que se vuelva a ejecutar el chequeo. Si algun event listener es ejecutado (eventos del mouse o del teclado, etc) los ejecuta.
- Chequea si hay cambios, si los hay actualiza la pantalla.
- Repitir.

Conclusiones importantes:

- Este ciclo de chequeo se repite infinitamente durante la ejecucion de nuestra aplicacion, sea que tengamos 1 o tengamos miles de Frames, el FP solo le importa saber si hay cambios que se tengan que reflejar en la pantalla y el gustosamente se encargara de chequearlo. Cambios pueden ser: dibujar algo (graphics.drawLine,etc), mover el X o Y o el width o height de nuestros componentes o los componentes dentro de nuestra aplicacion, cambiar el color de algo, etc.
- Los cambios que hagamos dentro de una funcion a nuestros componentes visuales no se reflejaran inmediatamente en pantalla (aunque a veces parezca que si), sino hasta que nuestro codigo termine de ejecutarse y el cambio proceso de rendereo se ejecute. Por ejemplo si tenemos algo como: comp.width = 100; comp.height = 200; dentro de un metodo, esto NO quiere decir que FP vayaa ejecutar nuestro codigo asi:
1. Cambie el width.
2. Dibuje la pantalla con el nuevo width.
3. Cambie height.
4. Redibuje la pantalla con nuevo height
El FP ejecutara el redibujado de la pantalla hasta que nuestro codigo se termine de ejecutar.
- Aunque nuestras aplicaciones no tengan muchos frames (2 en el caso de Flex) o solo 1 el evento ENTER_FRAME se va a despachar multiples veces porque el FP va a revisar si hay en cambios en la pntalla que deba actualizar. De ahi que el evento ENTER_FRAME sea utilizado multiples veces para ejecutar animaciones o procesos que deben ejecutarse infinitamente dentro de un mismo frame. Essto quiere decir que si tenemos un proceso que debe ejecutarse infinitamente, no debemos meterlo dentro de un ciclo infinito, digamos while(true), sino dentro de este event listener.
- El ciclo de rendereo, es realizado automaticamente por el FP.
- Si se esta ejecutando codigo de la aplicacion, el proceso de rendereo de la pantalla no se va a ejecutar y viceversa. Estos dos son exclusivos, no se puede chequear mientras se ejecuta codigo (funciones o event handlers) y no se puede ejecutar ningun metodo o event handler si se esta haciendo el chequeo. Por ejemplo, si nuestro frame rate es de 10 fps quiere decir que el FP va a revisar en teoria cada 100ms (1000 ms = 1 segundo, 1000 / 10 = 100 :) ) si hay que hacer una actualizacion. Pero como mencione arriba el framerate no necesariamente se va a ejecutar al mismo tiempo siempre. Si tenemos una rutina que recorre un Array con 1000 objetos por dentro y a cada objeto se le ejecuta algun metodo, una validacion y se le setea algunos valores, puede ser que esa funcion dure mas de los 100ms que esperaria el FP para revisar si hay cambios. Esto quiere decir que si la funcion demora 900ms, el FP no revisara si habra cambios hasta el siguiente segundo, no cuando se cumplan 200ms desde el primer chequeo.
- Si tenemos rutinas de codigo muy grandes, muy pesadas nuestra pantalla podria llegar a "congelarse" o verse "chunky", como pegada. Esto es porque como se expuso arriba la actualizacion de la pantalla no se va a realizar hasta que se termine de ejecutar nuestor codigo. Entre mas duren nuestras rutinas mas va a durar en refrescarse nuestra pantalla y peor puede ser la experiencia del usuario.
- Hay un tiempo maximo de ejecucion de codigo que por default es de 15segs. Si por ejemplo tenemos una clase y hacemos un ciclo while(true) en el constructor, podemos esperar 15 segs y ver como nuestra aplicacion va a mostrarnos un error. Esto es porque el tiempo maximo de ejecucion de una funcion fue excedida.

Formas de Optimizacion:

- Si tenemos rutinas muy grandes y que demoran mucho tiempo, lo mejor seria dividir esas rutina en varias para ejecutarse en distintos tiempos, algo como lo que se puede hacer con Threads en otros lenguajes. Recordemos que aunque el FP maneja Threads internamente, nosotros como desarrolladores no tenemos acceso a ellos y solamente podemos emularlos.
- Si utilizamos Flex, hagamos uso de los componentes creados en el framework que en su mayoria estan optimizados para este ciclo de actualizacion de pantalla. Si vamos a hacer nuestros propios componentes, sigamos las reglas y hagamos un override de los metodos sugeridos por Adobe (esto para FLEX 3) como commitProperites y updateDisplayList entre otros. Ambos metodos mencionados antes tienen su razon de ser una funcion especifica para hacer que se ejecuten las cosas de una mejor manera.
- Si no utilizamos Flex, podemos hacer uso del evento Event.RENDER. Este metodo es despachado por el FP exactamente antes de dibujar los cambios en la pantalla. Podemos recibir este evento haciendo un addEventListener normal, pero ademas de eso tenemos que llamar a stage.invalidate(). Esto forzara al evento a ser despachado. Ahora en que nos ayuda este evento? Pues al ser despachado justamente antes de ser actualizada nuestra pantalla, podemos revisar en nuestro listener, si nuestra clase tiene algun cambio en la pantalla. Si lo tiene, llama a la funcion que dibuje o haga los cambios que se quieran hacer en pantalla. Si no hay cambios simplemente no hacemos nada. Eso nos permite forzar al FP redibujar lo que cambio SOLAMENTE cuando haya cambios que de verdad alteren nuestra pantalla y forzar a que la actualizacion de la pantalla se haga solamente hasta que se tenga que hacer. Podemos hacer mas uso de esto, si ponemos setters en nuestros componentes que se encargue de registra que hay cambios en nuestro objeto en un flag booleano. En lugar de llamar dentro del setter al metodo que se encarga de dibujar nuestros graficos o mover nuestros componentes cada vez que se cambia una variable. El event handler del metodo renderer, consultara si nuestro flag esta activado y si lo esta ahi llamara a nuestro metodo. Asi en lugar de llamar el metodo que dibuja nuestra pantalla cada vez que se cambia una variable, este se ejecutara una sola vez y exactamente antes de que se ejecute el redibujado de la pantalla. Esto es muy parecido al proceso de optimizacion que tienen los componentes en Flex.

Otros recursos:
El excelente libro de Colin Moock, Essential Actionscript 3.0, especialmente el capitulo 23
Racetrack: Excelente analisis de como funciona el proceso de rendereo en el Flash Player.

domingo, 8 de noviembre de 2009

Eval function en Actionscript

Recordando mis tiempos de programador en Java, entre recientemente al site de una herramienta llamada Bean Shell que use hace varios a~nos... La herramienta sencillamente era un interprete de codigo en Java (y en otros lenguajes pues interpretaba Python y combinacion entre Python y Java), en tiempo de ejecucion, es decir sin tener que compilar un archivo .class y generar el bytecode para que sea ejecutado por el virtual machine...
Nosotros utilizabamos de esta funcionalidad para una herramienta administrativa, donde ejecutabamos scripts en un pseudolenguaje para consultar multiples y distintos servidores de informacion. Esto nos permitia tener multiples consultas dinamicas sin tener que recompilar la aplicacion principal o que los usuarios finales tuvieran que aprender a programar en algun lenguaje extra~no para ellos o usar SQL o algo por el estilo.
Viendo esto, me intereso encontrar algo parecido en Flash/Flex. La funcion Eval que esta disponible en multiples lenguajes, incluyendo Javascript, tiene una funcionalidad algo parecida, nos recibe de parametro una cadena de caracteres donde se tiene codigo que sera interpretado (y ejecutado) por esa funcion. En Flash era comun encontrar esta funcion (o algo parecido) en ActionScript 2 pero fue eliminada en la version 3.
Sin embargo haciendo uso del trabajo hecho en Tamarin Project de Mozilla, donde se tuvo acceso a parte del codigo del AVM2 osea el nuevo Action Virtual Machine que corre en el Flash Player 9.x y mas versiones mas recientes. Tamarin nos permite ver como funciona internamente el virtual machine, como se ejecuta el codigo, como se procesa, etc. Es algo bastante interesante y avanzado a la vez y permitiria la optimizacion de aplicaciones en la plataforma flash, incluso hay proyectos donde se promueve el uso de AOP o aplicaciones que convierten codigo de C# o Java a codigo ejecutable por el flash player... todo con la informacion que provee este proyecto; pero bueno, esto seran tema de otros posts.
Como decia anteriormente - antes de desviarme diciendo cuan impresionante es el proyecto - haciendo uso del proyecto Tamarin, "Metal Hurlant" (creador de multiples librerias open source como AS3Cripto) creo una libreria que se comporta como la funcion Eval, interpretando codigo de Actionscript en tiempo de ejecucion. Pueden acceder a un demo desde aqui.
Solo puedo decir que este es un trabajo brillante y que tomando las medidas de seguridad pertinentes (para que no se inyecte codigo maligno en tiempo de ejecucion entre otras) y no abusando de la misma por cuestiones de rendimiento (este proceso demanda algo de recursos) puede llegar a ser de mucha utilidad. La creacion de aplicaciones mas dinamicas, mas inteligentes en tiempo de ejecucion, etc. nos permitira ofrecer mejores aplicaciones a nuestros usuarios y a la vez creando aplicaciones menos complejas y flexibles... nuevamente sin abusar de esto...
Disfruten...

jueves, 29 de octubre de 2009

Oferta de Empleo - Desarrolladores Flex en Costa Rica

Si hay algun interesado en conseguir empleo como Flex Developer en Costa Rica, la empresa Rivet Logic esta buscando 3 desarrolladores en Flex ojala con experiencia en el uso de frameworks como Mate y PureMVC y algo de BlazeDS

Mas informacion con Manuel Calvo, en mcalvo@rivetlogic.com y aqui.

* Yo solo paso el mensaje :), no soy responsable del mismo o parte de la empresa.

domingo, 9 de agosto de 2009

Flex Unit 4

Recientemente salió al aire Flex Unit 4 (versión Beta en este momento). Esta versión incorpora muchas mejoras, incluyendo mucha funcionalidad incorporada de la libreria para pruebas Fluint, quien le dono muchas mejoras a la misma, sobre todo en el manejo asincronomo.
Debemos recordar que en Flex/Flash estamos dentro de un ambiente asincronimo, esto es: hacemos el llamado a una función pero no sabemos cuando se hara devolvera el llamado a la función. Esto ya que el Flash Player no soporta multi hilos y al hacer uso de ciertos recursos que no tenemos en realidad una idea clara de cuanto va a durar en responder (llamado al servidor, cargar una pelicula, etc) puede hacer que la aplicación termine pegandose y la experiencia de usuario sea demasiado desagradable.
Una de las nuevas caracteristicas incorporadas en esta versión es el uso de metadatas. Esta es una caracteristica utilizada en Flex sobre todo cuando marcamos una propiedad como [Bindable]. Mucha gente no esta al tanto que en Actionscript 3 uno puede crear sus propias metadatas y utilizarlas como quieran dentro de su aplicación, lo cual a mi gusto es demasiado elegante.
Otra nueva caracteristica es que ya no se hace uso de la herencia (para crear nuevos tests y suites), ahora se usan metodos estaticos al estar utilizando metadatas. Ademas podemos ejecutar nuestros tests con distintos Runners (Flex Unit, Fluint, air, etc) que nos brindaran distintas caracteristicas de acuerdo a nuestras necesidades.
A continuacion unos pocos ejemplos de algunos principios. Espero poder agregar mas con el tiempo.

Creación de Suites:
Los suites son un conjunto de tests. Podemos tener dentro de un suite multiples tests.

package tests
{
[Suite]
[RunWith("org.flexunit.runners.Suite")]
public class DelegatesTestSuite
{
//Tests se declaran como propiedades
public var test1:MiClaseTest;
}
}

Creando un Test con un delegate:

package tests
{
public class MiClaseTest
{
//Metodo asincronomo:
//Marcamos el metodo como test y lo colocamos como primero
//en la lista. Ademas le decimos que espere al menos 3500 ms
//para que nos devuelvan algun valor
[Test (async, timeout="3500",order=1)]
public function loginUser():void
{
var user:User = new User()
user.username = "user2";
user.password = "123xyz";

var delegate:UserDelegate = new UserDelegate();
var responder:IResponder = Async.asyncResponder(this, new
TestResponder(onLoginUserComplete, onLoginUserFault), 3000);
}

//Este es el handler que recibira elresultado del
//servidor.
//@param event ResultEvent del servidor.
//@param token, es el objeto inicial que pasamos en el llamado
private function onLoginUserComplete(event:Object, token:Object):void
{
Assert.assertTrue(event.result.authenticated);
}

private function onInsertUserFail(event:FaultEvent, token:Object):void
{
Assert.fail('Error loading user: ' + event.fault);
}
}
}

Creando Teorias:

Y que es esto? Es un nuevo concepto (al menos en el mundo de testing en Flex) Lo que nos dice es que si creemos que algo va a ejecutarse correctamente, tiene que ejecutarse correctamente con cualquier informacion que le sea pasada como parametro, por ejemplo, si debo encontrar que el valor absoluto de un numero va a ser siempre positivo, la teoria me dice que cualquier numero que le pase, va a ser mayor a 0. Entonces en mi test puedo poner un numero infinto de numeros a probar, solo que nosotros no tenemos tanto tiempo como para eso, entonces escogemos un conjunto finito de valores a probar y con ese conjunto validamos nuestra teoria.

Primero tengo que marcar la clase como que tiene una teoria, para que pueda ser procesada con el metadata [RunWith]

package tests
{
[RunWith("org.flexunit.experimental.theories.Theories")]
public class MiClaseTest
{
...
Creando un sets de datos para probar:
Ocupo 2 metadatas [ArrayElementType] utilizado en mxml para especificar el tipo de dato dentro de una coleccion y el metadata [DataPoints] que marca nuestros set como un conjunto para probar.

[DataPoints]
[ArrayElementType("Object")]
public static var usuariosValidos:Array = [
{username:"user1",password:"123xyz"},
{username:"user2",password:"344112"},
{username:"user3",password:"o5ii33"}
];
Creacion de un test con teoria:
Marcamos el metodo conel metadata [Test] y el metadata [Theroy]
[Theory]

[Test(async,timeout="10000")]
public function validUsers(usuarios:Object):void
{
var delegate:UserDelegate = new UserDelegate();
var responder:IResponder = Async.asyncResponder(this, new
TestResponder(onUserLoginComplete, onUserLoginFail), 2500);

delegate.authUser(usuarios.username, usuarios.password);
}

Esto hace que el test se ejecute la cantidad de datos que tengamos dentro de nuestro datapoint, en este caso se ejecutara automaicamente 3 veces.
Esto verdaderamente facilitara nuestro desarrollo en pruebas y nos permitira asegurarnos que podamos testear mejor nuestra aplicacion con menor esfuerzo

Otros Recursos
Introduccion (mejor link que he visto)
Excelente Tutorial
Pruebas Integracion
Importancia Pruebas y Feedback

Integrando aplicaciones y sobreviviendo a ello

- "Ya está listo! Dalé probá!!"
- Mmmmm... no amigo, no funciona!
- "Es en serio?? Si yo lo probé!"
- Si... pero no funciona! Te voy a enviar el log con el error para que lo revises.
- "Ok mandalo! Solo que voy saliendo, pero lo veo mañana a primera hora..."











Photo By Zach Klein


Y así termina otro día para el programador de front end, donde no pudo avanzar todo lo que quería y donde tendrá que atrasarse unas horas mas para poder terminar sus tareas.

Esta es una historia repetida diariamente para muchos programadores de clientes para internet, donde sus aplicaciones son apenas la interfaz de acceso para sus usuarios a servicios con bases de datos, servicios externos y demas aplicaciones que pueda tener un sitio corporativo.

Hablando con mi colega y amigo Ivan Alvarez - quien trabaja en la Bolsa Nacional de Valores en Mexico desarrollando aplicaciones financieras de ultima tecnología con Adobe Flex y Java en el lado del servidor - nos dimos cuenta que nuestros trabajos aunque son en areas totalmente distintas (yo trabajo para Scrapblog un sitio en Flex para crear tarjetas y manualidades digitales) enfrentamos estas mismas situaciones aunque estemos a miles de millas de distancia, con gente completamente distinta.


Photo by: http://www.lumaxart.com/

La integración de aplicaciones con clientes en Flex y código de servidor se puede convertir muchas veces en una tarea titánica y dolorosa. Sin embargo estamos convencidos que no debe ser así:
  • Existen distintas formas para comunicarse: Webservices, Rest Services y Remote Objects.
  • Los tres metodos son robustos, probados y comprobados.
  • Para Remote Objects, existe un protocolo de comunicacion (para la serializacion y deserializacion de la informacion) definido por Adobe que es AMF3. Este protocolo es bastante rapido, comprimido y binario lo cual hace que la informacion se transmita mas rapido.
  • Este protocolo ha sido implementado multiples veces para distintas plataformas, empezando con Java (BlazeDS, LifeCycle Data Services, Weborb, GraniteDS), .Net (Weborb, FluorineFx), Rails (Weborb, RubyAMF), PHP(Weborb, AMFPHP), entre otras. Esto quiere decir que puedes hacer tu backend en el lenguaje que quieras y utilizar esta implementación de AMF para comunicar tu aplicación Flex con el servidor de manera rapida, robusta y segura.
Con estos antecedentes, podemos decir que crear aplicaciones en Flex conectada a un servidor de aplicaciones con bases de datos o cualquier servicio que se ocupe es bastante sencillo. Sin embargo el problema que mas sufrimos es cuando tratamos de comunicarnos con los servicios expuestos por nuestro servidor. Generalmente hemos visto los siguientes problemas:
  • Los servicios no estan correctamente configurados y por lo tanto es imposible a nuestras aplicaciones accesarlos.
  • El nombre de los métodos no son los mismos que como se definió previamente (si es que tiene la suerte que le definan los nombres de sus servicios en algún lugar como un Wiki, email o un documento más oficial.
  • La signatura de los métodos no es la misma que la que esta documentada (error muy parecido al anterior)
  • El servicio no fue probado y sus métodos tiran excepciones cuando son llamados. Este es el mas común. Parece que nuestros amigos de backend nunca prueban, ya sea por Unit Testing o al menos ejecutar desde un cliente la invocacion al método. Esto tan simple, puede ayudarlos a ellos a darse cuenta mas tempranamente que hay errores y arreglarlos antes de decirnos que ya esta listos nuestros servicios.
  • Problemas de serialización al enviar la información. Debemos recordar que hay una capa intermedia entre nuestra aplicacion cliente y nuestro servidor. Ese se va a encargar de convertir nuestra informacion y datos en terminos que nuestra contra parte pueda entender. Por ejemplo algunas implementaciones del AMF3 tienen problemas a la hora de serializar fechas (zonas de horario, 24 horas vrs 12 -AM/PM, etc), otras problemas a la hora de serializar numeros, las enumeraciones por ejemplo son estructuras que no todas las implementaciones soportan. Este tipo de problemas hacen que la integración sea mas lentas, es un constante hacer/probar/repetir.
Ahora, todo esto presentado anteriormente no quieredecir que no hay manera de solucionar esta situación:

  • Documentacion de los servicios, métodos, parametros, valores de retorno,excepciones, etc. No tiene que ser una documentacion de 3 paginas por servicio. Lo minimo debe incluir eso que puse arriba. Muchos desarrolladores sienten pereza de hacer esta documentacion y ahi es donde empiezan los problemas.
  • Uso de unidades de prueba (o algún tipo de prueba) en el código del servidor que sea ejecutado antes de "entregar" el código.
  • Como dije anteriormente, existe una capa intermedia entre nuestro cliente y el servidor y ocupamos probar que esa capa funciona correctamente, por eso es bueno probar nuestros clientes y los respectivos llamados al servidor con utilidades como Flex Unit 4, Fluint, etc. Incluso algunas herramientas para llamados remotos (como Weborb) incluyen consolas para probar directamente estos servicios desde un ambiente creado en Flex.
  • Investigar la herramienta que utilizamos y conocer cuales son problemas conocidos en las mismas. Investigar más del proceso de serialización esto nos ayudara a reconocer posibles problemas tempranamente.
  • Aprender un poco como es el desarrollo en el lado del servidor. Si tienes ese conocimiento vas a tener un valor agregado en el mercado y ademas vas a conocer más del proceso y poder ayudar a detectar errores, sugerir formas de implementación, etc.
  • Enseñar. Si tienes estos conocimientos de arriba, enseñar a otros desarrolladores sobre todo esto. Iniciar la chispa en ellos para que investiguen igual. Esto debe ser de conocimiento para la mayoría de personas en el proyecto.
  • Cruzar los dedos y esperar que todo salga bien... :-P

Saludos!

Posts Relacionados

Integracion de Aplicaciones
Pruebas de Integracion
Llamadas Asincronimas
Interaccion con sistemas remotos

sábado, 16 de mayo de 2009

La importancia del Feedback y las pruebas

Recientemente escribi sobre la importancia de recibir feedback en nuestra profesion de infomaticos.
No voy a extenderme mucho al tema, mucho ya lo dije en el post anterior sin embargo hoy quiero hablar un poco sobre la importancia de hacer pruebas y como se relaciona con el feedback.
Veran, las pruebas que hagamos (me gusta usar Fluint para flex y ultimamente estoy probando con Flex Unit 4 - version alpha en este momento) son una forma de feedback para nuestras aplicaciones y para nosotros mismos.
Cuando hagamos cambios grandes o refactoty en nuestro codigo y ejecutemos las pruebas que hayamos realizado sabremos sabremos si los cambios realizados por nosotros han afectado el comportamiento correcto de nuestra aplicacion. Eso tambien es feedback.
Cuando durante el fin de seman un companero de trabajo cambie algo en su codigo y lleguemos el lunes y nada funcione... podemos correr nuestras pruebas y darnos cuenta que es lo que fallo y encontrar la solucion de forma mas rapida (ademas de poder culparlo :o) ). Eso tambien es feedback.
Soy partidario del TDD (Test Driven Development) y reconozco la importancia de las pruebas, como forma de feedback y de asegurar una mejor calidad en mi desarrollo, pero tambien reconozco que a veces el tiempo no alcanza o el cliente no entiende la importancia de estas pruebas. Por eso es necesario ser prudente a la hora de escoger que probar y que no. Como decia una abuela mia "Ni mucho que queme al santo ni tan poco que no lo alumbre". Repito Nada malo con probar, pero tambien ser concientes de nuestros tiempos ya que no siempre tendremos el suficiente tiempo para probar todo.
Mis secciones favoritas para probar, son las que estan en constante cambio y que son criticas:
logica de negocio, acceso a datos (servicios remotos o a base de datos en AIR).
Componentes y vistas me gusta probarlos separados, aislarlos en una aplicacion aparte y probar su funcionamientos, estilos, etc. Eso me provee Feedback. Me gusta aislar las vistas que haga y sus interacciones basicas y proveerlas a quien sea que este a cargo de esa vista, sea el disenador grafico o el encargado del proyecto o cliente del mismo. Que jueguen con la vista por separado en lugar de tener que cargar toda la aplicacion y gastar mas tiempo en proveerme feedback, eso lo pueden hacer en otro momento. Existen herramientas para probar la interfaz como Flex Monkey y Selenium que permite grabar interacciones y ejecutarlas automaticamente. Tambien son validas.
Flex Unit 4 Alpha viene con muchas mejoras y cosas nuevas, verdaderamente lo recomiendo! Aqui mas info

Creando APIs en Actionscript

Recientemente he tenido en mis ratos libres la mania de bajar API's para Actionscript 3 de diferentes servicios que hay por ahi, como Digg, Twitter, Facebook, Salesforce, etc para probarlos, jugar con ellos y hacer alguna aplicacion sencilla con ellos aunque nunca vaya a ser utilizada.
Esto me divierte en realidad y mas importante me ayuda a ver codigo de otras personas, maneras de pensar y de implementar. Creo que es una experiencia enriquecedora. Muchos desarrolladores piensan que ver el codigo de otros es malo, es bajo, es denigrante. Honestamente creo que no! Primero yo escojo de quien veo el codigo y la mayoria de personas que hacen estos APIs son mucho mas competentes que yo! Ademas es una manera de aprender de mejorar y de desarollar mejor. Un claro ejemplo es el acceso que tenemos al framework de Flex. Si algo puedo decir de mi actual trabajo y de los dos maestros de Flex con los que trabajo es que se conocen ese framework de arriba a abajo. De ahi que puedan hacer las cosas que hacen.
Bueno siguiendo con mi fascinacion tan geek de las ultimas semanas, me he puesto a pensar en que requisitos son necesarios para construir un API en ActionScript.

Primero pensemos para que necesitamos realizar un API. Un API es utilizado para ofrecer una serie de servicios que puedan ser invocados por otras aplicaciones con el fin de ejecutar una accion. No es lo mismo que un framework. El API debe ser claro, sencillo y definido. Mejor si esta documentado. Mejor aun si tiene ejemplos. El API debe ser facil de usar, intuitivo y tener todo lo que nuestros futuros clientes vayan a ocupar para interactuar con nuestra plataforma. Incluyendo objetos definidos por nosotros mapeando la informacion de nuestros servicios.

Segundo analicemos la forma en que vamos a entregar nuestra informacion. Aqui desde dos perspectivas distintas:
a) Como se accedera a la informacion que se quiere facilitar (ya pensando en algo mas "fisico"). Esto incluye como se haran los llamados a nuestros servicios: REST Services? Web Services? Remoting? External Calls (como tiene el API de Facebook)? Todo esto debe ser transparente para el usuario de nuestro API. Si acaso lo mas es la opcion de escoger que tipo de canal usar para comunicarse con nuestros servicios, pero la implementacion y demas no debe ser de importancia para el.
b) La forma en que entregaremos la informacion recolectada de nuestros servicios. Si recibimos XML, no podemos pasarle simplemente XML al cliente y dejar que el piense que va a hacer con esa informacion (tecnicamente si podemos, pero no debemos :) ). La creacion de objetos que mapeen nuestro servicio hace que nuestro API sea mas facil de usar.

Tercero consideremos en la naturaleza Asincronima de nuestra plataforma. Cuando hacemos una invocacion a un servicio externo sea por WebService, Remoting o simple REST Services no sabemos cuando vamos a recibir la informacion de vuelta. Esto hace que nuestros APIs no sean tan facil de usar cuando invocamos servicios remotos como hacer:

var misUsuarios:ArrayCollection = miAPI.cargarUsuarios(); //ESTO NO FUNCIONA!!

El metodo cargarUsuarios puede demorar un tiempo (incluso has segundos) en devolvernos esta informacion, asi que la asignacion a mis usuarios no va a ser correcta.

Soluciones:
a) Una forma de hacerlo es pasarle al metodo el arraycollection que queremos cargar y cuando se reciba la informacion se carguen los resultados en esa variable pasada como parametro. Recordemos que nuestros objetos en AS3 se pasan por referencia y no por valor, asi que los cambios que hagamos al objeto pasado por parametro, se reflejaran en nuestro objeto original (a menos que se haga una copia del mismo. En lo personal la siento como valida, pero no es aplicable en todas las ocasiones. A veces ocupamos darnos cuenta cuando algo fue procesado y eso se logra a traves de eventos.

b) Otra forma de hacerlo es atraves del uso de eventos. Cuando nuestra funcion recibe el resultado, esta manda un evento indicando que fue recibido. Anadiendo un event listener a ese evento, podemos procesar esa informacion desde donde queramos. Algo importante es aislar cada llamada o cada proceso de datos por aparte, para que cada llamada despache un solo evento, en lugar de estar llamando handlers de otras locaciones por eventos que se invocan con otros propositos. Por supuesto es importante recordar el removeEventListener una vez que es ejecutado un event handler que no se ocupa tener mas y poner las referencias como weak, pero igual si no se aislan las llamadas pueden crear conflictos.

Esta practica es seguida en el API para Facebook, a continuacion parte del codigo de uno de sus ejemplos:

var call:AddComment = new AddComment(story_id, body);
call.addEventListener(FacebookEvent.COMPLETE, onAddComment);
facebook.post(call);


onAddComment Va a encargarse de utilizar la informacion recibida como se quiera, puesto que ya esta informacion viene procesada y convertida en el tipo de dato que se quiere todo esto cuando se despache el evento de Complete.

c) Otra forma de hacerlo, es aislando el resultado de la funcion invocada y que ella se encargue de manejar el resultado. Esto es como lo que hacen con el API de Digg . Esto es delegar la llamada y el procesamienta del resultado y posterior conversion a objetos normales a un objeto que es devuelto por nuestra funcion invocada. Por ejemplo:

Del API de DIGG

public static function getUser(user:*):UserResponse
{
var request:URLRequest = new URLRequest(getUserURL(user));
return load(request, new UserResponse()) as UserResponse;
}


Esta clase devuelve un UserResponse, que hereda de la clase Response que a su vez es la que hace el llamado al servicio y delega en UserResponse el procesamiento y conversion del resultado en un objeto utilizable en la aplicacion y no simple XML.

Como ven, enfoques distintos, pero el mismo principio aislar la invocacion para que pueda ser tratada como una llamada distinta.

Espero esto pueda ayudar a otras personas que tengan que crear APIs para servicios externos para AS3 o que anden buscando como ingresar a esto de APIs y servicios externos y que puedan de este humilde texto encontrar algo que les ayude
Disfruten...

lunes, 30 de marzo de 2009

Programacion Modular - II Parte

Hace un tiempo escribi sobre los modulos en Flex y aun tengo algo que quisiera compartir y que aprendi hace poco.
Casi siempre cuando se crea un modulo, se extiende de la clase mx.modules.Module (si es en MXML) o de la clase ModuleBase si es en Actionscript.

Ahora, que hay en esa clase Module que la hace tan especial??

En si como tal, la clase no tiene nada especial mas que un metadata que vamos a revisar pronto. La clase Module extiende de "mx.core.LayoutContainer" que extiende a su vez de la clase "Container"; clase base de la mayoria de los componentes contenedores que utilizamos como Box (y sus decendientes: VBox, Hbox), Canvas, etc. Esto quiere decir que por si mismo el modulo nos permite agregarle componentes, como lo hariamos en otro componente contenedor.

Sigamos con el Module, si revisamos el codigo que viene el framework vemos lo siguiente en la clase:

package mx.modules
{

import mx.core.LayoutContainer;

[Frame(factoryClass="mx.core.FlexModuleFactory")]

Encontramos el metadata [Frame]

Sobre este metadata tenemos muy poca informacion, sin embargo es utilizada en otras clases del framework, como es el caso de la clase Application, que siempre utilizamos. Por ejemplo Application utiliza "mx.managers.SystemManager". Aunque siempre pensemos que la clase Application es la base de nuestra aplicacion, en realidad es SystemManager, es la primer clase que se ejecuta, se encarga de setear los eventos principales, cargar las librerias necesarias y pasar al siguiente frame, donde estaria nuestra aplicacion.

Las aplicaciones Flex tienen siempre 2 frames, el primero cuando se corre el preloader y se cargan los recursos necesarios de la aplicacion (RSL, etc) y el segundo donde se tiene la aplicacion en si. Este metadata nos permite especificar la creacion de un framework e indicarle cual clase debe ejecutarse en ese frame. En el caso del Module, le pedimos que ejecute la clase "mx.core.FlexModuleFactory", que si vamos a su codigo podemos entender lo siguiente:
  • Implementa la interfaz "IFlexModuleFactory" al igual que SystemManager. Esta interfaz define dos metodos: create() e info() que nos devuelve la informacion necesaria para cada uno de los modulos.
  • Extiende la clase "MovieClip" que es la unica que nos permite tener mas de un frame a la vez.
  • Una vez que los recursos necesarios por el modulo son cargados la clase se encargara de pasar al siguiente cuadro, con nuestra aplicacion. Esto cuando este todo cargado. Algunas veces usando External RSL el tiempo de carga se alarga y esto es porque no pasara hasta el siguiente cuadro hasta que este todo cargado.
Ahora.. aparte de teoria en general que mas nos provee esto?? Pues haciendo uso del metadata "Frame" y de la clase "FlexModuleFactory" podemos crear a partir de componentes contenedores nuestros modulos con comportamiento especifico. Por ejemplo modulos que se comporten como TitleWindows, como Panels, etc. o incluso como algun componente contenedor que definamos nosotros; solamente ocupamos agregar el metadata
[Frame(factoryClass="mx.core.FlexModuleFactory")]
Esto es super util cuando queremos imitar un mismo estilo entre varios modulos, se crea un componente base, con el comportamiento y estilos repetidos a traves de la aplicacion y posteriormente en lugar de crear modulos basados en "Module" se crean basados en "ComponenteCustomizado"

Espero pueda servir de algo y ampliar un poco el conocimiento en este tema que podemos agregar nuevas cosas a nuestras aplicaciones de manera elegante y optima. El metada "Frame" podria tambien permitir agregar nueva funcionalidad si extendemoslas clases correctas.

jueves, 19 de marzo de 2009

Binding / No Binding

Binding y no Binding...

Hace un tiempo escribi un post sobre binding y a continuacion muestro un ejemplo del uso del mismo.
Este ejercicio muestra la diferencia a la hora de actualizar objetos que usan binding y no.
Se tiene una clase que se llama Producto, con dos campos nombre y precio. Se cargan dentro de un ArrayCollection (que provee binding por si mismo) y se bindea el array collection a un datagrid. Cada vez que se selecciona un producto de la lista, se rellenan los campos de abajo con un objeto bindeado tambien. Al modificar dichos campos y apretar "Update", modificamos directamente el objeto seleccionado asi:

var prod:Product = products.getItemAt(grid.selectedIndex) as Product;
prod.name = namet.text;
prod.price = Number(price.text);

La aplicacion utilizando binding en la clase Product automaticamente nos refresca los campos modificados en el grid. La aplicacion que no utiliza binding al contrario se queda quieta... Si apretamos "reload" veremos los cambios aplicados.
Si en este mismo ejemplo, en lugar de actualizar el producto que esta dentro de la lista, crearamos una nueva instancia de un objeto Product y actualizaramos en el Array Collection con este nuevo objeto, el grid se modificaria automaticamente ya que el ArrayCollection provee binding por si mismo. Algo asi

var prod:Product = new Product();
prod.name = namet.text;
prod.price = Number(price.text);

products.setItemAt(prod, grid.selectedIndex);

El ejemplo trata de mostrar las diferencias entre ambos casos y la importancia de conocer cuando utilizar binding y cuando no.

Con Binding




Sin Binding





Codigo Aqui

martes, 10 de marzo de 2009

Degrafa Patterns






Update (2009-03-29): Download Code Here Example below



I've been trying to spend sometime learning Degrafa, a very nice declarative graphics framework for Flex.
I really like it and enjoy it. It is a very useful tool, specially because it lets you do in few lines very powerful graphic oriented tasks, like the one I just did below...
This pretty simple application allows you draw an icon in a grid, preview how the Icon will look in different sizes and then draw that icon into a canvas and display it as a pattern, that you can interact with since you are able to rotate it. All this using a some Bitmaps, BitmapData and the Surface, Rectangular and VectorFill objects from Degrafa with no hassle...
*Hopefully* I'll upload the code soon but this is a good example of how simple and powerful Degrafa is; for now feel free to try the final application...



Click here to run the application

BTW... did I mention Degrafa has a lot of examples and documentation on their site and that in fact it is an open source project?? :)

viernes, 6 de marzo de 2009

After Flex Camp Miami

Flex Camp was very good, I enjoyed looking that much people interested in Flash/Flex/related technologies here in Miami. Saw some nice projects and ideas. Specially loved the speeches from Christian Saylor about "The Art of Story Telling" - UX related - and Brian LeGros talking about continuous integration and some very good ideas for enterprise development in Flex. He sure has a lot of experience in development processes.
After the event was over I had a chance to talk with some of the guys of Universal Mind and with Laura Arguello and Nahuel Foranda who are the creators of Mate a very nice framework for flex, They are very nice guys and of course a Latin Orgullo :) Good work guys!!
Hope to see more stuff like this in Miami... a Flex User Group maybe??

martes, 3 de marzo de 2009

Flex Camp Miami

Este viernes 6 de Marzo es el Flex Camp aqui en Miami... en realidad estoy bastante emocionado por el evento, hay buenos expositores y algunos de los temas me parecen muy interesantes. El precio.. me parece simbolico, $30.00 con almuerzo incluido.
De las sesiones que mas me interesan estan:
In Search of AOP for AS3 -> Maxim Porges
Spring & BlazeDS Integration -> Jeremy Grelle
Continuous Integration and Flex -> Brian LeGros
Mate Flex Framework -> Laura Arguello

http://flexcampmiami.com/

--

This Friday is the Flex Camp here in Miami. I'm really looking forward to this event. Last year I had a chance to organize with my past company a Flex Camp in Costa Rica (presenting Mike Downey) and it was a great experience.
The price this time is almost symbolic: $30.00 including lunch...
I'm really excited about the following sessions:

In Search of AOP for AS3 -> Maxim Porges
Spring & BlazeDS Integration -> Jeremy Grelle
Continuous Integration and Flex -> Brian LeGros
Mate Flex Framework -> Laura Arguello

http://flexcampmiami.com/

domingo, 14 de diciembre de 2008

Flash Catalyst

Update - Junio 1 2009
Para bajar el beta de Catalyst pueden hacerlo desde aquí. Mas info aquí
Se encuentra en versiones para windows y mac.

A pocas semanas de una presentacion mas oficial de Flash Catalyst (previamente conocido como Thermo) tuve la oportunidad de asistir a una presentacion sobre el tema en el Grupo de Usuarios de Adobe en Atlanta. Fue una excelente oportunidad para ver la herramienta, hacer preguntas y ver la respuesta de los disenadores y programadores acerca de la herramienta, quienes a final de cuenta son quienes van a utilizarla.
Para quienes aun no saben que es, Flash Catalyst es una herramienta ideada por Adobe para el diseno de aplicaciones RIA, donde se le ofrece a los disenadores la oportunidad de verse involucrados en el desarrollo de la aplicacion de una manera mas sencilla y directa. Actualmente un disenador puede entregarle a los programadores una guia de estilos, imagenes cortadas, skins, etc y es responsabilidad del desarrollador en Flex la de poner esos elementos dentro de la aplicacion, sabiendo de antemano que por regla de dedo para la mayoria de desarrolladores si una imagen quedo en el pixel 253 y el disenador la queria en el 250, es lo mismo; sin embargo los disenadores sufren al ver tales alteraciones a su diseno y se viene la lucha por que quede todo igual como se muestra en el diseno original.
Este tipo de escenario en Flex, se ve muy repetido y de ahi la necesidad de crear una aplicacion que le permitiria al disenador ingresar al flujo de trabajo de la aplicacion. Catalyst permitiria al disenador importar sus disenos desde un PSD o archivo de Ilustrador o Fireworks o incluso crear ciertos elementos basicos desde su IDE, a partir de ahi podra convertir sus disenos en ciertos componentes de Flex con unos cuantos clicks, por ejemplo... podemos tener una caja de colores y el disenador con un par de clicks, lo puede convertir en un boton de Flex y la herramienta por si misma generaria el codigo MXML necesario para eso, que sera provisto posteriormente al programador. Se podran tambien crear estados (que esto cambiara con el Flex 4 de la manera en que se maneja actualmente), animaciones, etc y todo a unos cuantos cliks de distancia.
Programador y disenador podran hacer cambios a los archivos MXML desde Flex Builder u otra herramienta y se supone que Catalyst sera lo suficientemente inteligente para reconocer esos cambios y procesarlos recreando asi los cambios en los archivos sin tener que hacer todo de nuevo, mejorando muchisimo el flujo e interaccion de diseno-programacion.

Status Actual:
  • Catalyst funciona unicamente con el Suite CS4.
  • Funciona unicamente con Flex 4 (que esta en etapa de prueba igualmente)
  • Funciona actualmente solo en Mac OSX
  • Se encuentra en una fase muy temprana de desarrollo y se espera sacar un release por ahi de finales del 2009.
Ventajas:

En mi opinion Catalyst podra:
  • Mejorar flujo y comunicacion entre disenadores y programadores.
  • Mejorar los procesos de desarrollo en empresas que utilicen ambos grupos.
  • Creacion de Prototipos (esto es lo que mas me gusta). Ya los disenadores e incluso personas de UX podrian crear prototipos funcionales sin necesidad de utilizar un programador o usar muy poco de ellos.
Este servidor tiene una copia de Catalyst con la que estara jugando en los proximos dias, mientras vaya encontrando cosas interesantes las pondre por aqui...
Saludos

lunes, 3 de noviembre de 2008

Smartfox Server - Servidor Juegos para Flash

Como muchos de los hits de este blog vienen de un blog dedicado a la creacion de juegos en Flash y Flex y como tengo un poco(muy poco) de experiencia en esa area sobre todo tratando con servidores para juegos o para chat, he decidido subir un pequeno codigo que crea una muy simple aplicacion en Flex que se encarga de conectarse a un servidor de juegos que se llama SmartFoxServer que es uno de los varios servidores de juegos para flash. Este esta basado en Java lo cual permite que el servidor corra en Linux, Windows o Mac OS sin ningun problema. La documentacion y ejemplos es bastante buena, aparte de un buen soporte del vendedor.
Este ejemplo funciona con la licencia gratuita del Smartfox Pro, que es para 20 usuarios concurrentes. Es una simple comunicacion de chat(envio de mensajes) entre varios usarios, conectados a un cuarto, aunque puede crecer utilizando variables de usuario, variables de cuarto ambas excelentes para la creacion de MMOs o Juegos masivos donde los usuarios ven como se mueven los otros usuarios en tiempo real... creacion de cuartos dinamicos, etc, etc, etc.
El servidor es muy completo, lo unico es que su escalabilidad no es tan sencilla aunque ahora se brinda una solucion con Terracota, una utilidad que nos permite tener varias maquinas virtuales en varios servidores, como si fuera una sola.

Codigo adjunto, la clase que maneja la interaccion es: SmartfoxInteraction.as, el servidor de SFS debe estar corriendo antes de ejecutar la aplicacion.
Saludos

jueves, 23 de octubre de 2008

Costa Rica Java User Group

Que bueno fue poder haber asistido a la reunion del Grupo de Usuarios de Java de Costa Rica hoy en la Ulatina... aparte de que fuera una excelente oportunidad para conocer a otros desarrolladores en otras areas, fue excelente poder ver la exposicion de Ben Galbraith y de Dion Almaer.
Estos dos son de los mejores expositores que he visto en mi vida. Una claridad... tanto en los slides usados como en los ejemplos como en la interaccion entre ambos, el conocimiento que tienen... sin palabras!!! En cuanto al contenido de la presentacion bastante claro, empezando por una EXCELENTE introduccion a la necesidad de crear mejores experiencias de interactividad al usuario y como una interfaz no solo bonita, sino que cumpla con el objetivo del usuario puede marcar la diferencia (mostraron bastantes ejemplos). Ademas, fue impresionante ver el desarrollo que ha tenido AJAX y lo que esta pronto por salir... pude ver cosas que pense nunca poder ver en un browser sin correr una maquina virtual como el Flash Player o Java Virtual Machine. Igual... no cambio a Flex... aunque lo que vi fue bastante impresionante y esto ayuda a que todo se ponga mejor y haya mas competencias para brindar mejores experiencias a los usuarios.
Felicidades a Maricel la organizadora del grupo y su grupo de ayudantes... iniciativas de este tipo y otras que ya hay, son las que ocupamos para poder crecer como pais en conocimiento y tecnologia...
Por cierto, en la rifa del final me gane un excelente libro... Yaaayyy!!!

viernes, 17 de octubre de 2008

Pruebas - Integracion de Aplicaciones

Aunque nuestros desarrolladores de lado del servidor prueben su codigo, y nosotros probemos nuestro codigo (con flex unit, mercury, flexmonkey o lo que queramos usar) el proceso de integracion entre cliente y servidor es necesario probarlo con ambos capas interactuando juntas (no solo por aparte) y de manera continua y automatizada para comprobar cualquier cambio o problema que se pueda encontrar.
Con Flex el problema es que nuestros llamados son asincronimos y no tenemos idea cuando vamos a recibir la informacion de vuelta. Esto hace que nuestros tests usando FlexUnit (la principal unidad de pruebas para flex) pasen efectivamente aunque la respuesta del servidor no sea correcta (esto por la naturaleza sincronica del flexunit) ya que el assert no se ejecuta hasta que se regrese el llamado del servidor y la unica forma de arreglar esto es usando un pequeno hack con un Timer, que la verdad hace el diseno de pruebas complicado, tedioso y dificil de mantener.
En cambio utilizando la unidad de pruebas llamada Fluint tenemos una orientacion completa a llamados asincronimos. La naturaleza de la unidad es esa y falicita las pruebas no solo de llamadas remotas, sino tambien de creacion de componentes, integracion de componentes, etc. Su documentacion aunque no es la mejor es bastante buena y el codigo es abierto. Tiene ademas un Runner de las pruebas que es ejecutable en AIR,  y genera reportes en archivos XML intepretables por parte de alguna herramienta que utilicemos para el continuous integration, como Cruise Control o Hudson
En general Fluint cumple mas alla de mis expectativas ya que su soporte asyncronimo es perfecto para todo lo que ocupamos probar, a diferencia de lo que hacer FlexUnit. Mas adelante quisiera exponer un poco con herramientas de automatizacion de pruebas como Mercury o Flex Monkey que parece ser una excelente opcion open source para esto.
Todo esto como buenas practicas que desarrolladores de Flex deberiamos de tener en nuestro repertorio... Son cosas MUY importantes y que crearan un desarrollo mas fluido y tranquilo. 
Aqui un pequeno y muy BASICO ejemplo para probar llamadas remotas:
/**
* Prueba, invocamos al metodo login de nuestro servicio con
* los parametros 'username y 'password'
* y se crea un responder de tipo TestRespoder que provee Fluint para
* poder saber quien recibira que en nuestro llamado
*/
public function testLoginService():void
{
var responder:IResponder = asyncResponder(
new TestResponder( handleResult, handleFault ) , 3000 );
var token:AsyncToken = remote.getOperation('
login').send("username",
"password");
token.addResponder(responder);
}

/**
* Handle del result de la llamada. Hacemos el Assert.
*/
private function handleResult( data:Object, passThroughData:Object ):void
{
trace(data);
assertNotNull(data);
}

/**
* Handle del fault de la llamada. Inmediatamente despachamos un
* Fail del test.
*/
private function handleFault( info:Object, passThroughData:Object ):void
{
fail("Received fault from Server: " + info);
}


sábado, 4 de octubre de 2008

Integracion de Aplicaciones con Flex

Recientemente me solicitaron dar un training para desarrolladores de Flex para Java. Mi proposito era primordialmente presentar la herramienta de Flex a nuestros desarrolladores (que son bastantes) y a la vez enfocarme en la necesidad de estandarizar el proceso de la creacion de aplicaciones que utilicen ambas tecnologias.

Mi transfondo tecnico viene de Java y hace cuestion de dos anos le agregue a mi carrera el Flex. Fue una desicion dificil y confusa por la falta de conocimiento de dicha tecnologia, pero al final creo que tome la desicion correcta. Java y Flex es una mezcla excelente para la creacion de aplicaciones y tener un conocimiento en ambas tecnologias me ha podido dar una valor agregado para ofrecer.

Creo que en esto de aplicaciones con Flex y Java hay mucha tela que cortar. He hablado previamente de tecnicas como el remoting, llamadas asincronimas y otras cosas que nos permiten comunicarnos con el servidor para interactuar en nuestra aplicacion, sin embargo el sentido de este post va mas orientado al proceso y trabajo que tiene que haber para unir a estos dos juntos...
Flex como front end provee muchas ventajas que otras herramientas no pueden proveer en un 100%, empezando por que el virtual machine donde corre (Flash Player) esta instalado en mas de un 95% de las computadoras del mundo. Java, un lenguaje maduro, activo, con una comunidad de desarrolladores de mucha experiencia y que va rejuveneciendose poco a poco es una excelente desicion para construir aplicaciones transaccionales. La ventaja con Flex es que no solamente tiene que trabajar con Java, el puede trabajar con .Net, Ruby, PHP, etc... lo cual permite que la escogencia del servidor de aplicacion sea mas flexible.

Pero como dije.. este post no va en lo tecnico, que es mejor?, cual es mas rapido?, etc... este post va mas orientado al proceso de integracion entre Flex y una aplicacion de servidor, escrita en el lenguaje que usted quiera. Parte de mis conocimientos tecnicos hablare mas sobre java.
He podido trabajar en varias aplicaciones de tamano considerable en las que se usa Flex y una aplicacion en el servidor (Java en cada caso y ayude en una con PHP). En todos los casos noto lo mismo:

La integracion es la etapa mas dificil de todo.

Una incorrecta integracion hace que todo el desarrollo sea mucho mas lento. Podemos desarrollar nuestra aplicacion Flex en un dia y la aplicacion en el servidor en un dia tambien... y la integracion de algo sencillo puede tomar 2 dias mas...
Aqui una lista de razones por las que pienso esto pasa:
  • Falta de comunicacion entre los equipos de desarrollo. No se mantienen reuniones entre los equipos donde se definan que servicios, metodos, parametros y tipos de retorno se van a maneja o cambios que se hayan realizado. Esto hace que sea todo una caja negra, que se trate de integrar algo y se pasen parametros equivocados, que se llamen a metodos incorrectos, que se esperen valores distintos. 
  • Relacionado con lo anterior... no existe documentacion de los servicios expuestos por la aplicacion para ser accesados desde el front end. Si existiera una documentacion detallando descripcion, nombre del metodo, parametros, tipo de retorno, etc. que pueda ser accesado por todos los desarrolladores, en un solo lugar (wiki, etc.) facilitaria muchisimo la comunicacion y el desarrollo no se veria tan parado al hacer la integracion.
  • No existen por lo general pruebas de integracion. Podemos crear JUnits para probar nuestros metodos en Java, podemos crear Flex Units para probar metodos en Flex, pero por lo general no existe un mecanismo para probar la integracion. Por que es necesario probar esto? Bueno.. aunque nuestros JUnits salgan correctamente, debemos recordar que en el medio (entre Flex y nuestro back end) hay una capa de comunicacion en lo que pueden pasar muchisimas cosas, desde tipos de datos no reconocidos, nombres incorrectos de metodos hasta problemas con el servidor, que debemos ser capaces de probar. Mi propuesta inicial es hacer Flex Units con soporte para operaciones asincronimas que sean ejecutadas desde la maquina del developer del Back End y se encarguen de llamar los metodos remotos. Si algo falla en esos tests units a la hora de interactuar con los servicios o metodos provistos por nuestro back end, podran ser revisados y corregidos por parte de nuestros desarrolladores. Los programadores en Flex mientras tanto, pueden continuar con otras tareas sin tener que esperar a que cada vez que algo falle, sean arreglados.
Otra herramienta que he visto y me parece muy interesante es el uso de Mercury Pro, que viene con el Flex Builder y te permite crear pruebas de aplicaciones a modo de macros o robot, donde se graba una interaccion con una aplicacion y se graba toda la secuencia para probar que siempre de el mismo resultado. Igualmente si Flex Unit no te es funcional, puedes crear tu propia unidad de pruebas, talvez demore mas tiempo pero te dara mayor tranquilidad.

Otros pensamientos relacionados:

  • Quien lleva la batuta a la hora de escoger que metodos o servicios se van a exponer en una aplicacion al front end? Sera tarea solo del back end o tarea del front end? Estoy convencido que es una tarea de ambos equipos y que la comunicacion tiene que ser clave y en doble via. Front End provee una perspectiva de lo que necesita ser ingresado por el usuario para funcionar, pero back end provee una vision completa de todo lo que ocurre en un sistema y no solo en una pantalla. Nada peor que una aplicacion disenada enteramente por pantallas.. de ahi mi consejo de establecer estos servicios y metodo de forma conjunta.
  • Aunque de pereza y duplique el trabajo, es NECESARIO el uso de DTO's o Value Objects para comunicar informacion del back end al front end, sobre todo si se usa Remoting. Esto es necesario para evitar problemas con sesiones, enumeraciones y otras cosas que no esten aceptadas por Flex y que vayan a ser recibidas incorrectamete ademas nos permite obtener abstracciones mas exactas a lo que necesitemos.

Espero poder ahondar en otros temas relacionados a esto en un futuro...

sábado, 20 de septiembre de 2008

Flex Tag Cloud Component Version 0.1 - English Below...







Trabajando en un proyecto personal en AIR, encontre la necesidad de usar un componente de tipo Tag Cloud Lo primero que hice fue buscar por un componente hecho en Google, pero no pude encontrar nada asi que decididi empezar a disenar el mio. El resultado esta arriba.
El componente es rellenado con un Array de Tags. Un Tag es un objeto con tres propiedades: tagId,description y count; el primero un identificador unico y numerico del tag en caso que se necesite, el segundo la descripcion o texto del tag y el ultimo la cantidad de repeticiones de un tag, que indicaran el tamano del tag en el componente. Cuando se presiona un tag se despacha un evento tipo TagCloudEvent con la informacion del tag.
Aun no esta completo, se necesita trabajar en estilos y poner el codigo disponible en alguna forma, por ahora se puede bajar un SWC con el componente y el ejemplo.

Ejemplo
Componente


While working a personal project in AIR I ran into the need of using a simple sort of "Tag Cloud" component. I decided to "googled" out for a component already created but I wasn't able to find anything so decided to sit and create my own component.. it's not perfect and still needs a lot of work (specially with styles) but is functional...
The Component is filled with an array of Tag objects. A Tag object contains a numerical Id, a description and a count with the amount of appearances of the tag which is used to decide the size of it in the cloud. When a Tag is clicked a TagCloudEvent is dispatched with the information of the tag so that you can use that information to search or do what ever you need...
As I said there's still a lot of work needed to be done and will release it's code later, for now you can download the swc component and the example of how to use it.

Example
Component