TAG | Spring
18
Swiz Framework (brutalmente simple)
2 Comentarios · Posteado por Martin en Air, AS3, Ejemplos, Swiz, Tutoriales
En este post me gustaría exponer un poco de las interesantes cualidades que encontré revisando este relativamente nuevo framework, o como le gusta decir a los norteamericanos la segunda generación de frameworks para Flex, o mejor dicho para AS3.
Swiz es un framework muy liviano y que introduce la idea de inversión de control o (ioc) de sus siglas en ingles, también dispone obviamente de inyección de dependencia para cumplir con su objetivo. Para la gente que conoce un poco de Java, seguramente ya se le vino la primavera a la mente…si “Spring” jajaja . Swiz propone la misma idea que Spring en java, pero claro con sus diferencias obvias, pero la idea es básicamente la misma.
Para la gente que no conoce mucho de patrones de diseño, ni de arquitectura de software en general, la IOC es conocida y adoptada por ayudar a la reducción de código redúndate, y aquí viene lo bueno, ya que tendremos que escribir menos código. jajaja
Sin más preámbulo, he pensado en reescribir el sencillo ejemplo que hice en el post anterior con Swiz, así pueden ver lo fácil que es de implementar este framework.
Lo primero q tenemos que hacer es bajar el bajar el swc que contiene al framework de esta dirección: http://code.google.com/p/swizframework/
Y copiarlo dentro de nuestra carpeta libs.
Sería bueno que armemos una pequeña estructura MVC de paquetes, esto no es necesario pero ayuda mucho al orden.
Algo así sería más que suficiente:
Lo primero que necesitamos crear es, lo que en Swiz se conoce como un “Bean Loader” y esto se hace simplemente extendiendo un componente del tipo BeanLoader, que viene incluido en el framework. Se vería así:
<BeanLoader xmlns="org.swizframework.util.*"
xmlns:mx="http://www.adobe.com/2006/mxml" >
<model:DnsModel
id="DnsModel"
xmlns:model="com.martinbove.model.*" />
<controllers:DnsController
id="DnsController"
xmlns:controllers="com.martinbove.controllers.*"/>
</BeanLoader>
Ahora necesitamos inicializar el framework desde el punto de entrada de nuestra aplicación. Para este fin Swiz posee un componente que se encarga del trabajo.
<swiz:SwizConfig strict="true"
mediateBubbledEvents="true"
eventPackages="com.martinbove.events"
viewPackages="com.martinbove.views"
beanLoaders="{[Beans]}" />
Seguiremos con la creación del modelo de datos, que en este caso es tan sencillo como esto:
package com.martinbove.model
{
public class DnsModel
{
[Bindable]
public var informacion:String = new String();
public function DnsModel()
{
}
}
}
En el código del controlador es donde se pueden ver un poco la magia de Swiz. En este caso el controlador espera la llamada desde la vista, luego procesa dicha llamada, en nuestro caso efectuando un dns lookup, y seguidamente altera el modelo de datos como respuesta, que a su vez se ve reflejado en la vista nuevamente.
package com.martinbove.controllers
{
import com.martinbove.model.DnsModel;
import flash.events.DNSResolverEvent;
import flash.events.ErrorEvent;
import flash.net.dns.AAAARecord;
import flash.net.dns.ARecord;
import flash.net.dns.DNSResolver;
import flash.net.dns.MXRecord;
import flash.net.dns.PTRRecord;
import flash.net.dns.SRVRecord;
import org.swizframework.controller.AbstractController;
public class DnsController extends AbstractController
{
public var dnsResolver:DNSResolver;
// aquí se inyecta el modelo en esta variable usando la meta etiqueta [Autowire]
[Autowire]
public var dnsModel:DnsModel;
// constructor de la clase
public function DnsController() {
// se inicializa el objeto DNSResolver y se agregan 2 manejadores que se usaran para las consultas de DNS
dnsResolver = new DNSResolver();
dnsResolver.addEventListener(DNSResolverEvent.LOOKUP, lookupHandler);
dnsResolver.addEventListener(ErrorEvent.ERROR, errorHandler);
}
// en este caso registramos a este metodo como manejador del evento DnsEvent.DNS_LOOKUP mediate la etiqueta [Mediate]
[Mediate(event="DnsEvent.DNS_LOOKUP", properties="dnsType, queryString")]
public function lookupDNS(dnsType:String, queryString:String ):void {
switch(dnsType)
{
case "ARecord":
dnsResolver.lookup(queryString, ARecord);
break;
case "AAAARecord":
dnsResolver.lookup(queryString, AAAARecord);
break;
case "MXRecord":
dnsResolver.lookup(queryString, MXRecord);
break;
case "PTRRecord":
dnsResolver.lookup(queryString, PTRRecord);
break;
case "SRVRecord":
dnsResolver.lookup(queryString, SRVRecord);
break;
}
}
// Manejador de resultados de busqueda de DNS
public function lookupHandler(event:DNSResolverEvent):void
{
var records:Array = new Array();
records = event.resourceRecords;
var name:String = "Name: " + records[0].name;
var ttl:String = "TTL: " + records[0].ttl;
// aqui directamente escribimos en el modelo de datos el resultado
dnsModel.informacion += name + "\n";
dnsModel.informacion += ttl + "\n";
if (records[0] is ARecord) {
var addr:String = "Addr: " + records[0].address;
dnsModel.informacion += addr;
}
else if (records[0] is MXRecord) {
var exchange:String = "Exchange: " + records[0].exchange;
var preference:String = "Preference: " + records[0].preference;
dnsModel.informacion += exchange + "\n" + preference;
}
else if (records[0] is PTRRecord) {
var ptr:String = "PTR: " + records[0].ptrdName;
dnsModel.informacion += ptr;
}
else if (records[0] is SRVRecord) {
var priority:String = "Priority: " + records[0].priority;
var weight:String = "Weight: " + records[0].weight;
var port:String = "Port: " + records[0].port;
var target:String = "Target: " + records[0].target;
dnsModel.informacion += priority + "\n" + weight + "\n" + port + "\n" + target;
}
dnsModel.informacion += "\n----------------------------------------------------------------------------\n";
}
// Manejador de errores
protected function errorHandler(event:ErrorEvent):void {
dnsModel.informacion += "Ha ocurrido un error en la consulta";
dnsModel.informacion += "\n----------------------------------------------------------------------------\n";
}
}
}
La comunicación entre la vista y el controlador la hacemos mediante un evento propio, esto es básicamente extender la clase base event y añadirle las propiedades que necesitemos.
package com.martinbove.events
{
import flash.events.Event;
public class DnsEvent extends Event
{
public static const DNS_LOOKUP:String = "DnsEvent.DNS_LOOKUP";
private var _dnsType:String;
private var _queryString:String;
public function get dnsType():String {
return _dnsType;
}
public function get queryString():String {
return _queryString;
}
public function DnsEvent(type:String, dnsType:String, queryString:String, bubbles:Boolean = false, cancelable:Boolean=false)
{
super(type, bubbles, cancelable);
_dnsType = dnsType;
_queryString = queryString;
}
override public function clone() : Event {
return new DnsEvent(type, dnsType, queryString, bubbles, cancelable);
}
}
}
La vista también es muy sencilla, y solo tiene que despachar el evento cuando se realiza la consulta.
El código es el siguente:
<?xml version="1.0" encoding="utf-8"?>
<s:Group xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/halo" >
<fx:Script>
<![CDATA[
import com.martinbove.events.DnsEvent;
import com.martinbove.model.DnsModel;
import flash.events.MouseEvent;
import org.swizframework.Swiz;
// aqui sigue la magia del framework que solo se encarga de inyectar el dnsModel
[Autowire]
[Bindable]
public var dnsModel:DnsModel;
protected function button_clickHandler(event:MouseEvent):void {
var tipo:String = tipos.selectedItem.label;
// creamos el evento q se manejara en el controller mediante la etiqueta [mediate]
var e:DnsEvent = new DnsEvent(DnsEvent.DNS_LOOKUP, tipo, queryString.text, true);
dispatchEvent(e);
}
]]>
</fx:Script>
<s:Group width="90%" horizontalCenter="0" top="20">
<s:layout>
<s:HorizontalLayout/>
</s:layout>
<s:TextInput id="queryString" width="100%" text="www.martinbove.com.ar"/>
<mx:ComboBox editable="false" id="tipos">
<fx:Array>
<fx:Object label="ARecord" />
<fx:Object label="AAAARecord" />
<fx:Object label="MXRecord" />
<fx:Object label="PTRRecord" />
<fx:Object label="SRVRecord" />
</fx:Array>
</mx:ComboBox>
<s:Button label="consultar" click="button_clickHandler(event)"/>
</s:Group>
<s:Group top="86" width="90%" horizontalCenter="0" height="90%">
<s:layout>
<s:HorizontalLayout/>
</s:layout>
<s:TextArea id="resultado" width="100%" height="100%" text="{dnsModel.informacion}"/>
</s:Group>
<s:Label x="20" y="66" text="Resultados" color="#FFFFFF"/>
</s:Group>
Con esto hemos concluido la recorrida por esta breve aplicación que muestra la implementación de Swiz, aquí les dejo el código fuente de la aplicación de ejemplo para q lo pueda evaluar con más tranquilidad y algunos recursos por si quieren seguir viendo algo más sobre este framework.
- http://swizframework.org/
- http://www.madeinflex.com/2009/07/01/el-principio-de-inversion-of-control-y-flex/
- http://groups.google.com/group/swiz-framework/
ActionScript air beta 2 AS3 BeanLoader Codigo Flex Framework inversion de control inyeccion de dependecia IOC Java Patrones de diseño Resolución DNS Spring Swiz tutorial


