Bloques estáticos en AS3
Los bloques estáticos son bloques de código pertenecientes a una clase que se ejecutan una única vez cuando la clase en cuestión es cargada por primera vez en la AVM.
Dentro de un bloque estático se puede ejecutar cualquier tipo de expresión y referenciar a otras clases pero se debe tener en cuenta que desde el bloque, al estar dentro del ámbito de la clase (no de la instancia, de ahí que se llamen bloques estáticos), solo se pueden referenciar las propiedades y métodos estáticos de la clase.
Un bloque estático es equiparable a un constructor pero dentro del ámbito de clase (no de instancia).
El siguiente código muestra el uso de un bloque estático a modo de inyección de dependencias dinámico:
-
/* Archivo.as */
-
package com.joangarnet.persistencia {
-
-
import flash.system.Capabilities;
-
-
public class Archivo implements IArchivo{
-
static private var archivoImpl:IArchivo;
-
-
/* bloque estático */
-
{
-
if( Capabilities.playerType == "Desktop" ){
-
// guarda en el sistema de archivos del O.S.
-
archivoImpl = new ArchivoAIR();
-
}else{
-
// guarda en web
-
archivoImpl = new ArchivoFlex();
-
}
-
trace( Capabilities.playerType );
-
}
-
-
/*
-
* implementacion de IArchivo
-
*/
-
public function guardar():void{
-
archivoImpl.guardar();
-
}
-
-
public function borrar():void{
-
archivoImpl.borrar();
-
}
-
}
-
}
-
-
/* IArchivo.as */
-
package com.joangarnet.persistencia{
-
public interface IArchivo{
-
function guardar():void;
-
function borrar():void;
-
}
-
}
-
-
/* ArchivoAIR.as */
-
package com.joangarnet.persistencia{
-
public class ArchivoAIR implements IArchivo{
-
public function guardar():void{
-
trace("guardar() en el sistema de archivos local")
-
}
-
-
public function borrar():void{
-
trace("borrar() en el sistema de archivos local")
-
}
-
}
-
}
-
-
/* ArchivoFlex.as */
-
package com.joangarnet.persistencia{
-
public class ArchivoFlex implements IArchivo{
-
public function guardar():void{
-
trace("guardar() vía web")
-
}
-
-
public function borrar():void{
-
trace("borrar() vía web")
-
}
-
}
-
}
TestBloqueEstatico.mxml
-
<?xml version = "1.0" encoding = "utf-8"?>
-
<mx:Application xmlns:mx = "http://www.adobe.com/2006/mxml" layout = "absolute">
-
<mx:Script>
-
<![CDATA[
-
import com.joangarnet.persistencia.Archivo;
-
-
private var f:Archivo = new Archivo();
-
]]>
-
</mx:Script>
-
<mx:Button click = "f.borrar()" label="borrar" />
-
<mx:Button click = "f.guardar()" label="guardar" />
-
</mx:Application>
Si se ejecuta en el contexto de una aplicación AIR y clicamos en los dos botones borrar y guardar respectivamente se mostrará en la consola:
borrar() en el sistema de archivos local guardar() en el sistema de archivos local
Si de lo contrario se hace desde el navegador se mostrará:
borrar() vía web guardar() vía web
Comments
4 Responses to “Bloques estáticos en AS3”
Leave a Reply












Hola Joan. Muy bueno lo de los bloques estáticos, realmente no sabía que existían.
De seguro que hoy mismo le encuentro utilidad en mis codigos.
Muchas gracias por compartir el tip.
Saludos!
Muy interesante ;)
Los conocía pero nunca me he visto en la necesidad de utilizarlos.
Saludetes
Buenas Joan,
el ejemplo es muy didactico!! :-) Pero creo que es bueno añadir alguna puntualización importante.
Como bien comentas los bloques estáticos se ejecutan al cargar la definición de una clase en el AVM. El hacer un uso indevido de estos bloques puede relantizar su inicialización.
Si las clase es una clase que se carga dentro de una aplicación Flex yo personalmente optaria por la utilizacion de [Mixin]. Basicamente al marcar una clase como Mixin tendremos que implementar un metodo estatico public static init ( sm : ISystemManager). Este metodo sera invocado durante el ciclo de instanciacion de la aplicacion desde SystemManager. Este es el mecanismo para inicializar las implementaciones para las clases de automatizacion o accesibilidad en la SDK.
Por otro lado cabe destacar que los bloques estaticos son bloques interpretados en tiempo de ejecucion y no en tiempo de compilacion. En el ejemplo del post yo quizas optaria por compilacion condicional o el uso de un contenedor IoC que inyectara la instancia apropiada. De esta forma ahorrariamos el linkar clases innecesarias en el swf resultante.
Yo usaria los bloques estaticos para inicializar propiedades estaticas. Y la pregunta es... Cual es la diferencia entre
public static var myVar : String = "hola";
y
public static var myVar : String;
{
myVar = "hola";
}
En esta caso ninguna diferencia, pero las variables se ejecutan antes que el bloque estatico. Esto lleva a que los bloques estaticos pueden utilizarse para inicializar variables mas complejas que hagan uso de las otras variables:
public static const VAL1 : String = "val1";
public static const VAL2 : String = "val2";
public static const map : Object = new Object();
{
map[ VAL1 ] = new MyClass();
map[ VAL2 ] = new MyClass();
}
Volviendo al ejemplo del post. Habria otra forma bastante freak de conseguir el mismo efecto que consistiria en el uso de namespaces. Podrias definir todos los metodos en distintos namespaces en la misma clase:
package
{
public class TestClass
{
private namespace air_ns;
private namespace flex_ns;
private var currentNS: Namespace = air_ns;
public function guardar(): void{
currentNS::guardar();
}
public function borrar() : void {
currentNS::borrar();
}
air_ns function guardar():void
{
trace("air guardar");
}
air_ns function borrar():void
{
trace("air borrar")
}
flex_ns function guardar():void
{
trace("flex guardar");
}
flex_ns function borrar():void
{
trace("flex borrar");
}
}
}
para usarlo:
var tc : TestClass = new TestClass();
tc.guardar();
donde podrias inicializar de forma estatica currentNS con la logica que quisieras. El uso de namespaces aporta una forma sencilla para desarrollar polimorficamente. En este caso todas las implementaciones quedarian linkadas en el swf final (aumentando su tamaño)
Hola Xavi,
los Mixins me parecen una muy buena alternativa a los bloques estáticos dentro del marco de Flex porque en este caso te aseguras de que la ejecución se realiza *siempre* en un punto muy temprano de instanciación del framework. En el caso de los bloques estáticos es cuando la clase es realmente cargada en la AVM, lo cual puede suceder en cualquier momento y no necesariamente al iniciarse la aplicación...
Por otro lado, llámame freak si quieres, pero me gusta que pongas el ejemplo de los namespaces porque precisamente hice algo parecido en un ejemplo de un post anteior tratando los espacios de nombres: http://www.joangarnet.com/blog/?p=428#toc-pseudo-sobrecarga-de-metodos pero esta vez mostrando un ejemplo de pseudo sobrecarga de métodos.
Sé que el ejemplo aquí propuesto no es ni mucho menos el más apropiado... pero es que en realidad no se me ocurren demasiados casos de uso para esta rareza sintáctica que son los bloques estáticos XD
Gracias por el aporte ;)