Un ejemplo del patrón Proxy
Quiero salvar una lista de usuarios registrados, pero no sé exactamente donde. La cuestión es que dependiendo del valor de un checkbox ( en el que el usuario elige si está conectado a internet o no ), debo mandar los datos a servidor ( en formato XML ) o guardarlos en disco en un Shared Object
¡Esta es una misión para el patrón Proxy. ¿ Por qué?. Porque quiero aislar el proceso de guardar los datos del resto del programa, simplemente quiero decir, "eh, guardame esto" y olvidarme de cómo o dónde se guarda.
Eso es lo que hace este patrón. El proxy guarda una referencia a un objeto, que es quien realmente se encargará de ejecutar la acción. Pero es el proxy el que crea ese objeto, por lo que puede crear una instancia de una u otra clase dependiendo de ciertas condiciones en tiempo de ejecución
Por tanto, todas las clases que puedan ser instanciadas por el proxy, deben implementar el mismo interfaz. Y dependiendo del tipo de proxy, puede ser una buena idea que incluso él mismo implemente ese interfaz, para que se pueda eliminar si es necesario.
Basta ya de literatura. Primero, el interface:
interface ISaveable
{
public function saveUserList( theList: Array );
}
Sencillo, ¿no?. Queremos salvar una lista de usuarios, por lo tanto hemos definido un método saveUserList
Ahora, la clase que se encarga de enviar los datos a servidor
class myXML extends XML implements ISaveable
{
private var userArray: Array;
function myXML( )
{
this.userArray = new Array( );
}
function sendData( )
{
//this.sendAndLoad( );
}
public function saveUserList( theList: Array )
{
trace( "The XML is handling the data" );
this.userArray = theList;
//create the XML nodes, and send to server
}
}
Nada complicado. Simplemente un método público que recibe el array de usuarios, que se utilizará para crear el XML que se enviará a servidor
Bien, ahora la clase que guarda los datos en disco:
class mySO implements ISaveable
{
private var theSO: SharedObject;
private var userArray: Array;
function mySO( )
{
this.userArray = new Array( );
}
public function saveUserList( theList: Array )
{
trace( "The Shared Object handles the data" );
this.userArray = theList;
}
}
Esta clae implementa ISaveable, y al recibir los datos, intentará guardarlos en un Shared Object
Ahora la parte compleja. En este ejemplo, he representado el valor del checkbox ( el estado de la conexión ) utilizando una variable en _root. Pero para obtener el valo9r de esa variable, voy a utilizar un singleton. Simplemente, porque me parece una manera mejor, en este caso, que hacer una referencia directa a _root desde el proxy
class singleton {
private static var inst:singleton;
private function singleton() {}
public static function get instance():singleton {
if (inst == null) inst = new singleton();
return inst;
}
public function isConnected( ): Boolean {
return _root.connected;
}
}
Y, por fin, el proxy
class saveUserListProxy implements ISaveable
{
private var realClass: ISaveable;
function saveUserListProxy( )
{
var config: singleton = singleton.instance;
var conFlag: Boolean = config.isConnected( );
if ( conFlag )
{
this.realClass = ISaveable( new myXML( ) );
}
else
{
this.realClass = ISaveable( new mySO( ) );
}
}
public function saveUserList( theList: Array )
{
this.realClass.saveUserList( theList );
}
}
Y finalmente, en este ejemplo, en la línea de tiempo principal tendríamos:
var connected: Boolean = false;
var theUserList: Array = new Array( );
theUserList.push( { id: 0, name: "Cesar" } );
theUserList.push( { id: 1, name: "Javier" } );
var myProxy: saveUserListProxy = new saveUserListProxy( );
myProxy.saveUserList( theUserList );
Podeis probar que todo funciona cambiando el valor de la variable "connected"
Y eso es todo. Son casi las dos de la mañana de otra jornada laboral de casi 11 horas. Creo que ya va siendo hora de irse a la cama.....
Comentarios
Hola César,
Este post lo tenía guardado en "posts por mirar" ;).
...y por fin lo he podido probar y "degustar"...muy bueno, lo he disfrutado :)
Ahora bien, que ocurre con los Flasheros de habla hispana?, es que no les interesan esos temas, a mi me parece un ejemplo altamente interesante y reutilizable en proyectos propios. ¿como es que en la versión inglesa de este post hay ahora mismo 7 comentarios, y en esta 0 (pronto 1 ;)?
Esto le haría sentir a cualquiera que estamos solos en este tipo de intereses...¿no?
Mil gracia y saludos.
C.
Publicado por: Carlos Rovira | Junio 13, 2004 07:19 PM
Gracias, Carlos, me vas a subir los colores ;)
Es cierto que casi nunca hay comentarios en estos posts, pero yo siempre lo he achacado, citando a Mark Twain, a que "lo más difícil en esta vida es construir un buen ejemplo". De hecho, en parte es por eso también por lo que en el post inglés hay siete comentarios....
Gracias por tus ánimos.
Publicado por: Cesar Tardaguila | Junio 13, 2004 08:04 PM