Comunidad de diseño web y desarrollo en internet online

Comunicación entre Clases: DispatchEvent vs Funcion.call

Citar            
MensajeEscrito el 13 Feb 2012 08:42 am
muy buenas gente.

Estoy en un dilema. No se cual es mas efectivo a la hora de utilizar para poder comunicar varias clases.

En el DispatchEvent el unico incoveniente que le veo que tengo que añadir un ollente en el addEventListener para poder capturar ese momento y posteriormente eleminarlo si no se vuelve a utilizar.
Por otro lado, tengo Function y con el metodo call hago casi lo mismo, salvo que no tengo que estar eliminando nada.

Tengo un ejemplo sencillo donde puedo enseñaros a lo que me refiero. En este ejemplo os detallo un tipico cargador de imagenes externas donde hago referencia a los dos metodos a utilizar. Si no doy valores a las variabes de funciones actuo por eventos.

este es la clase:

Código ActionScript :

package
{
   import flash.display.Loader;
   import flash.system.LoaderContext;
   import flash.net.URLRequest;
   import flash.events.Event;
   import flash.events.ProgressEvent;
   import flash.events.IOErrorEvent;
   
    public class CargarImagen extends Loader
    {
      private var Carpeta: String= "imagenes/";
      private var Archivo: String;
      
      public var FuncionAbierto: Function; // Esquema --> function NombreFunction ()
      public var FuncionIniciado: Function; // Esquema --> function NombreFuncion (Ancho: Number, Alto: Number)
      public var FuncionProgreso: Function; // Esquema --> function NombreFuncion (bytesTotales: Number, bytesLeidos: Number)
      public var FuncionCompleta: Function; // Esquema --> function NombreFunction (NombreObjeto: DisplayObject)
      public var FuncionError: Function; // Esquema --> function NombreFunction (Error: IOErrorEvent)
      
      public function CargarImagen (Nombre: String)
        {
         super();
         
         Archivo= Nombre;
         
         this.contentLoaderInfo.addEventListener (Event.OPEN, estaAbierto);
         this.contentLoaderInfo.addEventListener (Event.INIT, estaIniciado);
         this.contentLoaderInfo.addEventListener (ProgressEvent.PROGRESS, estaProgreso);
         this.contentLoaderInfo.addEventListener (Event.COMPLETE, estaCompletado);
         this.contentLoaderInfo.addEventListener (IOErrorEvent.IO_ERROR, hayError);
        }
      
      public function Iniciar(): void
      {
         this.load (new URLRequest (Carpeta+Archivo), new LoaderContext ());
      }
      
      private function QuitarEventos (): void
      {
         this.contentLoaderInfo.removeEventListener (Event.OPEN, estaAbierto);
         this.contentLoaderInfo.removeEventListener (Event.INIT, estaIniciado);
         this.contentLoaderInfo.removeEventListener (ProgressEvent.PROGRESS, estaProgreso);
         this.contentLoaderInfo.removeEventListener (Event.COMPLETE, estaCompletado);
         this.contentLoaderInfo.removeEventListener (IOErrorEvent.IO_ERROR, hayError);
      }
      
      private function estaAbierto (e: Event): void
      {
         if (FuncionAbierto!=null) 
            FuncionAbierto.call (null)
         else
            dispatchEvent (new Event (Event.OPEN,false,false));
      }
      
      private function estaIniciado (e: Event): void
      {
         if (FuncionIniciado!=null) 
            FuncionIniciado.call (null,e.target.width,e.target.height)
         else
            dispatchEvent (new Event (Event.INIT,false,false));
      }
      
      private function estaProgreso (e: ProgressEvent): void
      {
         if (FuncionProgreso!=null) 
            FuncionProgreso.call (null,e.bytesTotal,e.bytesLoaded)
         else
            dispatchEvent (new ProgressEvent (ProgressEvent.PROGRESS,false,false,e.bytesLoaded,e.bytesTotal));
      }
      
      private function estaCompletado (e: Event): void
      {
         QuitarEventos();
         if (FuncionCompleta!=null) 
            FuncionCompleta.call (null,e.target.content) 
         else
            dispatchEvent (new Event (Event.COMPLETE,false,false));
      }
      
      private function hayError (e: IOErrorEvent): void
      {
         QuitarEventos();
         if (FuncionError!=null)
            FuncionError.call (null,e)
         else
            dispatchEvent ( new IOErrorEvent (IOErrorEvent.IO_ERROR,false,false,e.text,e.errorID));
      }
    }
}


Ahora para poder utilizarlo:
para utilizar "Function"

Código ActionScript :

import CargarImagen;

import flash.display.DisplayObject;

var Carga: CargarImagen= new CargarImagen ("Imagen.jpg");

Carga.FuncionCompleta= ImagenCompleta;
Carga.FuncionProgreso= ImagenProgreso;
   
Carga.Iniciar();

function ImagenCompleta (Imagen: DisplayObject): void
{
   addChild(Imagen);
}

function ImagenProgreso (BytesTotales: Number, BytesLeidos: Number): void
{
   trace(BytesLeidos+"/"+BytesTotales);
}


para utilizar Eventos

Código ActionScript :

import CargarImagen;

import flash.display.DisplayObject;
import flash.events.Event;
import flash.events.ProgressEvent;

var Carga: CargarImagen= new CargarImagen ("Imagen.jpg");

Carga.addEventListener (Event.COMPLETE, ImagenCompleta);
Carga.addEventListener (ProgressEvent.PROGRESS, ImagenProgreso);
   
Carga.Iniciar();

function ImagenCompleta (e: Event): void
{
   addChild(e.target.content);
   
   Carga.removeEventListener (Event.COMPLETE, ImagenCompleta);
   Carga.removeEventListener (ProgressEvent.PROGRESS, ImagenProgreso);
}

function ImagenProgreso (e: ProgressEvent): void
{
   trace(e.bytesLoaded+"/"+e.bytesTotal);
}


El caso es que el codigo es muy parecido entre uno y otro, y la efectividad creo que tambien (el tiempo de ejecucion es el mismo), de alli mi duda.

Agradeceria mucho vuestros comentarios y experiencia.

saludos

Por Yonomimi

76 de clabLevel



Genero:Masculino  

firefox
Citar            
MensajeEscrito el 14 Feb 2012 01:55 pm
En general, la arquitectura OOP siempre usa eventos, el motivo es porque es más desacoplado (no genera vínculos fuertes) y los participantes pueden subscribirse y desubscribirse en cuanto quieran, eso hace a la ductilidad. Una llamada directa implica acoplamiento, es decir si la función deja de existir o cambia de nombre, hay que ir cambiando las llamadas por todos lados. Una excepción a esto suelen ser los juegos, donde la velocidad es tan o mas importante como cualquir concepto de arquitectura, entonces si se suele usar llamadas directas porque son un pelin mas rápida que los eventos

Jorge

Por solisarg

BOFH

13669 de clabLevel

4 tutoriales
5 articulos

Genero:Masculino   Bastard Operators From Hell Premio_Secretos

Argentina

firefox
Citar            
MensajeEscrito el 14 Feb 2012 09:05 pm
Cierto es Jorge, en una arquitectura OOP hay que utilizar los eventos, y si observamos la clase de cargarimagen no se puede hacer sin eventos...xd....pero...para comunicarme con otra clase o con la clase principal tengo que "rebuznar" otra vez el evento (hacer un dispatchEvent) para poder recogerlo y con Funcion.call es como una extension de la funcion del primer evento.
primera clase:

usando Arquitectura OOP

Código ActionScript :

package 
{
   public class CLASE_UNO
   {
      public function CLASE_UNO ()
      {
         .
         .
         .
         this.addEventListener(Event.COMPLETE, estaCompletado);
      }

      private function estaCompletado(e: Event):void
      {
         this.removeEventListener(Event.COMPLETE, estaCompletado);
         dispatchEvent(new Event (Event.COMPLETE,false,false));
      }
   }
}

segunda clase

Código ActionScript :

package 
{
   public class CLASE_DOS
   {
      var claseUno: CLASE_UNO= new CLASE_UNO();
      
      public function CLASE_DOS ()
      {
         .
         .
         .
         claseUno.addEventListener(Event.COMPLETE, estaCompletado);
      }

      private function estaCompletado(e: Event):void
      {
         claseUno.removeEventListener(Event.COMPLETE, estaCompletado);
         dispatchEvent(new Event (Event.COMPLETE,false,false));
      }
   }
}

y usandolo

Código ActionScript :

var claseDos: CLASE_DOS= new CLASE_DOS()

clasedos.addEventListener(Event.COMPLETE, estaCompletado);

function estaCompleto (e: Event): void
{
   clasedos.removeEventListener(Event.COMPLETE, estaCompletado);
   funcionCompleto();
}

function funcionCompleto (): void
{
   
}


en contraposicion a con Function.call
primera clase

Código ActionScript :

package 
{
   public class CLASE_UNO
   {
      public Funcion: Function;
      
      public function CLASE_UNO (Funcion: Function)
      {
         this.Funcion= Funcion;
         .
         .
         .
         this.addEventListener(Event.COMPLETE, estaCompletado);
      }

      private function estaCompletado(e: Event):void
      {
         Funcion.call();
      }
   }
}

segunda Clase

Código ActionScript :

package 
{
   public class CLASE_DOS
   {
      var claseUno: CLASE_UNO;
      
      public function CLASE_DOS (Funcion: Function)
      {
         claseUno= new CLASE_UNO(Funcion);
         .
         .
         .
      }
   }
}

usandolo

Código ActionScript :

var claseDos: CLASE_DOS= new CLASE_DOS(funcionCompleto);

function funcionCompleto (): void
{
   
}

Por Yonomimi

76 de clabLevel



Genero:Masculino  

firefox
Citar            
MensajeEscrito el 15 Feb 2012 02:11 am
Si te gusta usar funciones en vez de eventos, todo bien, en todo caso te acordarás de esto cuando tengas que refactorizar un proyecto realmente grande ;)

Jorge

Por solisarg

BOFH

13669 de clabLevel

4 tutoriales
5 articulos

Genero:Masculino   Bastard Operators From Hell Premio_Secretos

Argentina

firefox
Citar            
MensajeEscrito el 15 Feb 2012 05:44 am
cierto jorge, rehacer un proyecto siempre es arduo y costoso...xd...que tengo ya algunas experiencias en delphi...xd

bueno...creo que tienes razon al 90% ...pero tienes que reconocer que Function en algun momento, muy especifico, puede solucionarte el problema

saludos

Por Yonomimi

76 de clabLevel



Genero:Masculino  

firefox
Citar            
MensajeEscrito el 15 Feb 2012 12:52 pm
Mientras te funcione a ti está perfecto

Jorge

Por solisarg

BOFH

13669 de clabLevel

4 tutoriales
5 articulos

Genero:Masculino   Bastard Operators From Hell Premio_Secretos

Argentina

firefox
Citar            
MensajeEscrito el 31 Jul 2012 10:31 am
Genial este post para ver la comunicación entre clases.

Gracias!!

Por Manolito_BCN

25 de clabLevel



 

firefox

 

Cristalab BabyBlue v4 + V4 © 2011 Cristalab
Powered by ClabEngines v4, HTML5, love and ponies.