SingletonPattern (VFP)

From codeWiki
(Difference between revisions)
Jump to: navigation, search
(Created page with "== Introduccion == El patron [http://en.wikipedia.org/wiki/Singleton_pattern Singleton] permite definir una clase que devuelve una referencia a una unica instancia de la mism...")
 
m (categorizacion)
 
(3 intermediate revisions by one user not shown)
Line 1: Line 1:
 +
__FORCETOC__
 +
 +
Por [[User:VictorEspina|VictorEspina]]
 +
 
== Introduccion ==
 
== Introduccion ==
  
 
El patron [http://en.wikipedia.org/wiki/Singleton_pattern Singleton] permite definir una clase que devuelve una referencia a una unica instancia de la misma cada vez que se intenta crear una nueva instancia.  Este patron es sumamente util cuando se desea manejar informacion comun a lo largo de la aplicacion y no se cuenta con clases estaticas, como es el caso de VFP.
 
El patron [http://en.wikipedia.org/wiki/Singleton_pattern Singleton] permite definir una clase que devuelve una referencia a una unica instancia de la misma cada vez que se intenta crear una nueva instancia.  Este patron es sumamente util cuando se desea manejar informacion comun a lo largo de la aplicacion y no se cuenta con clases estaticas, como es el caso de VFP.
 
  
 
== Clase SingletonPattern ==
 
== Clase SingletonPattern ==
Line 35: Line 38:
 
</source>
 
</source>
  
 +
La idea de usar dos clases es una forma de permitir aplicar el patron a cualquier clase y no necesariamente una basada en Custom. Sin embargo, si nuestra clase puede heredar de Custom entonces podemos simplemente heredar directamente de SingletonPattern:
 +
 +
<source lang="visualfoxpro">
 +
DEFINE CLASS appContext AS SingletonPattern
 +
Usuario = ""
 +
Empresa = ""
 +
ENDDEFINE
 +
</source>
  
 
== Codigo Fuente ==
 
== Codigo Fuente ==
Line 72: Line 83:
 
  className = ""
 
  className = ""
 
   
 
   
  PROCEDURE Init()
+
* Constructor
   IF NOT THIS.checkInstance()
+
* El parametro plInstance es utilizado por el metodo createInstance() en el caso
   THIS.createInstance()
+
* de que la clase real sea una subclase de SingletonPattern, para indicar que se
 +
* debe crear la instancia directamente
 +
  PROCEDURE Init(plInstanceMode)
 +
  IF plInstanceMode
 +
  RETURN
 +
  ENDIF
 +
  IF EMPTY(THIS.className)      && Si no se indica una clase real se asume
 +
  THIS.className = THIS.Class  && esta misma clase
 +
  ENDIF
 +
   IF NOT THIS.checkInstance()   && Se verifica si ya existe una instancia de
 +
   THIS.createInstance()       && la clase. Si no es si, se crea
 
   ENDIF
 
   ENDIF
 
  ENDPROC
 
  ENDPROC
 
   
 
   
 +
* checkInstance
 +
* Determina si ya existe una instancia creada para la clase real
 
  PROCEDURE checkInstance
 
  PROCEDURE checkInstance
   IF NOT ISNULL(THIS.getInstance())
+
   IF NOT ISNULL(THIS.getInstance())   && Si podemos obtener una referencia a la instancia
   RETURN .T.
+
   RETURN .T.                         && es porque la misma existe
 
   ENDIF
 
   ENDIF
   IF !PEMSTATUS(_Screen,THIS.className, 5)
+
   IF !PEMSTATUS(_Screen,THIS.className, 5)   && Si no existe la propiedad asociada a la clase
   _Screen.addProperty(THIS.className, NULL)
+
   _Screen.addProperty(THIS.className, NULL) && en _Screen, se crea
 
   ENDIF
 
   ENDIF
 
   RETURN .F.
 
   RETURN .F.
 
  ENDPROC
 
  ENDPROC
   
+
 
 +
  * createInstance
 +
* Crea una instancia de la clase real
 
  PROCEDURE createInstance
 
  PROCEDURE createInstance
 
   LOCAL oInstance
 
   LOCAL oInstance
   oInstance = CREATE(THIS.className)
+
   IF LOWER(THIS.Class) == LOWER(THIS.className)  && La clase real es una subclase directa de SingletonPattern ?
 +
  oInstance = CREATE(THIS.className, .T.)
 +
  ELSE
 +
  oInstance = CREATE(THIS.className)
 +
  ENDIF
 
   STORE oInstance TO ("_Screen." + THIS.className)
 
   STORE oInstance TO ("_Screen." + THIS.className)
 
  ENDPROC
 
  ENDPROC
   
+
 
 +
  * getInstance
 +
* Devuelve una referencia a la instancia unica de la clase real
 
  PROCEDURE getInstance
 
  PROCEDURE getInstance
 
   IF !PEMSTATUS(_Screen,THIS.ClassName,5) OR TYPE("_Screen." + THIS.className)<>"O"
 
   IF !PEMSTATUS(_Screen,THIS.ClassName,5) OR TYPE("_Screen." + THIS.className)<>"O"
Line 101: Line 132:
 
  ENDPROC
 
  ENDPROC
 
   
 
   
 +
* releaseInstance
 +
* Libera la instancia unica de la clase real
 +
PROCEDURE releaseInstance
 +
  IF THIS.checkInstance()
 +
  STORE NULL TO ("_Screen." + THIS.className)
 +
  ENDIF
 +
ENDPROC
 +
 +
* Accesor para la propiedad THIS
 +
* Este accesor decide si devuelve una referencia al controlador Singleton o a la clase real
 
  PROCEDURE THIS_Access(cMember)
 
  PROCEDURE THIS_Access(cMember)
   IF INLIST(LOWER(cMember),"classname","checkinstance","createinstance","getinstance")
+
   IF INLIST(LOWER(cMember),"classname","checkinstance","createinstance","getinstance","class")
 
   RETURN THIS
 
   RETURN THIS
 
   ELSE
 
   ELSE
Line 113: Line 154:
  
 
[[Category:Visual FoxPro]]
 
[[Category:Visual FoxPro]]
 +
[[Category:Patrones de diseño]]

Latest revision as of 07:46, 10 April 2012


Por VictorEspina

Contents

Introduccion

El patron Singleton permite definir una clase que devuelve una referencia a una unica instancia de la misma cada vez que se intenta crear una nueva instancia. Este patron es sumamente util cuando se desea manejar informacion comun a lo largo de la aplicacion y no se cuenta con clases estaticas, como es el caso de VFP.

Clase SingletonPattern

La clase SingletonPattern sirve como clase base para lograr convertir una clase cualquiera en un singleton. Lo unico que necesitamos es crear una clase basada en SingletonPattern que sera la que se instanciara a lo largo del progtrama, y la clase "real" que proporcionara la funcionalidad requerida.

Ejemplo:

* appContextClass es la clase real
DEFINE CLASS appContextClass AS Custom
 Usuario = ""
 Empresa = ""
ENDDEFINE
* appContext es la clase singleton que servira de puente para la clase real
DEFINE CLASS appContext AS SingletonPattern
 className = "appContextClass"
ENDDEFINE

Una vez hecho esto, toda instancia de appContext apuntara a una unica instancia de appContextClass:

LOCAL o1, o2
o1 = CREATE("appContext")
o2 = CREATE("appContext")
o1.Usuario = "VESPINA"
?o2.Usuario --> "VESPINA"

La idea de usar dos clases es una forma de permitir aplicar el patron a cualquier clase y no necesariamente una basada en Custom. Sin embargo, si nuestra clase puede heredar de Custom entonces podemos simplemente heredar directamente de SingletonPattern:

DEFINE CLASS appContext AS SingletonPattern
 Usuario = ""
 Empresa = ""
ENDDEFINE

Codigo Fuente

* SingletonPattern
* Clase para la implementacion del pattern Singleton en VFP
*
* Autor: Victor Espina
* Fecha: Abril 2012
*
* Uso:
* Para la implementacion de esta clase se requiere definir dos clases
* a) Una clase basada en SingletonPattern
* b) La clase real que se desea implementar como Singleton, la cual puede
*    estar basada en cualquier clase base o subclase.
*
* Ejemplo:
* Supongamos que tenemos una clase llamada AppContextClass que queremos
* implementar como singleton.  Lo unico que se debe hacer es declarar
* una clase basada en SingletonPattern y configurar su propiedad className:
*
* DEFINE CLASS appContext AS SingletonPattern
*  className = "appContextClass"
* ENDDEFINE
*
* Luego, cuando se desee crear una instancia de AppContextClass, se hace:
*
* oSingletonInstance = CREATE("appContext")
*
* Y se lograra el efecto de que todas las instancias de appContext apuntaran a
* una unica instancia de appContextClass.
*
* 
DEFINE CLASS SingletonPattern AS Custom
 *
 className = ""
 
 * Constructor
 * El parametro plInstance es utilizado por el metodo createInstance() en el caso
 * de que la clase real sea una subclase de SingletonPattern, para indicar que se
 * debe crear la instancia directamente
 PROCEDURE Init(plInstanceMode)
  IF plInstanceMode
   RETURN
  ENDIF
  IF EMPTY(THIS.className)      && Si no se indica una clase real se asume
   THIS.className = THIS.Class  && esta misma clase
  ENDIF
  IF NOT THIS.checkInstance()   && Se verifica si ya existe una instancia de
   THIS.createInstance()        && la clase. Si no es si, se crea
  ENDIF
 ENDPROC
 
 * checkInstance
 * Determina si ya existe una instancia creada para la clase real
 PROCEDURE checkInstance
  IF NOT ISNULL(THIS.getInstance())   && Si podemos obtener una referencia a la instancia
   RETURN .T.                         && es porque la misma existe
  ENDIF
  IF !PEMSTATUS(_Screen,THIS.className, 5)    && Si no existe la propiedad asociada a la clase
   _Screen.addProperty(THIS.className, NULL)  && en _Screen, se crea
  ENDIF
  RETURN .F.
 ENDPROC

 * createInstance
 * Crea una instancia de la clase real 
 PROCEDURE createInstance
  LOCAL oInstance
  IF LOWER(THIS.Class) == LOWER(THIS.className)   && La clase real es una subclase directa de SingletonPattern ?
   oInstance = CREATE(THIS.className, .T.)
  ELSE
   oInstance = CREATE(THIS.className)
  ENDIF
  STORE oInstance TO ("_Screen." + THIS.className)
 ENDPROC

 * getInstance
 * Devuelve una referencia a la instancia unica de la clase real 
 PROCEDURE getInstance
  IF !PEMSTATUS(_Screen,THIS.ClassName,5) OR TYPE("_Screen." + THIS.className)<>"O"
   RETURN NULL
  ENDIF
  RETURN EVAL("_Screen." + THIS.className)
 ENDPROC
 
 * releaseInstance
 * Libera la instancia unica de la clase real
 PROCEDURE releaseInstance
  IF THIS.checkInstance()
   STORE NULL TO ("_Screen." + THIS.className)
  ENDIF
 ENDPROC
 
 * Accesor para la propiedad THIS
 * Este accesor decide si devuelve una referencia al controlador Singleton o a la clase real
 PROCEDURE THIS_Access(cMember)
  IF INLIST(LOWER(cMember),"classname","checkinstance","createinstance","getinstance","class")
   RETURN THIS
  ELSE
   RETURN EVAL("_Screen." + THIS.className)
  ENDIF
 ENDPROC
 *
ENDDEFINE
Personal tools
Namespaces
Variants
Actions
Navigation
Toolbox