VB6 y las variables de modulo de clase en COM+

18/07/2003 - 20:40 por azimut | Informe spam
Hola, quisiera saber alguna opinión respecto a un asunto sobre
variables en módulos de clases Visual Basic 6 corriendo en COM+.

¿ Existe en realidad algún problema de "volatilidad" con las variables
de módulos de clase cuando se programa en tres o más capas (o niveles)
y todas las dlls (excepto obviamente la interfaz de usuario que corre
en los clientes, compuesta por forms y clases UserInterface) se
ejecutan en COM+ ?

Hasta donde yo tenía entendido, el problema (que como explicaré más
adelante puede ser también una solución) sucede únicamente con las
variables GLOBALES al proyecto (por ejemplo en módulos ".bas" de las
dlls que corresponden a las capas DataTransaction, BusinessRules o
DataAccess), que se declaran con la palabra Global.

Estas variables, cuando la dll está corriendo en COM+, son
"compartidas" por todas las instancias, de forma que si un usuario
accede a la dll y graba allí un valor, "le pasa por encima" al valor
que otro usuario le había instanciado previamente.
Esto sucede únicamente cuando la dll corre en COM+ porque el servicio
de componentes funciona de tal manera que "entrega" al usuario una
copia cualquiera (una instancia) y no se puede saber si la copia con
la que uno estaba trabajando tres o cuatro líneas de código más arriba
es la misma con la que estamos trabajando en la actual línea de código
(aunque hayan pasado sólo unos pocos milisegundos entre unas líneas de
código y otras) y eso les pasa debido a que las variables globales
ESCAPAN AL PARADIGMA DEL ENCAPSULAMIENTO.

Todo esto ocurre, dicho sea de paso, al margen de que uno haya seguido
religiosamente EN CADA METODO, "el ritual" de escribir
GetObjectContext(), crear la instancia X de la clase de la dll
corriendo en COM+, usarla -por ejemplo: X.UpdateCoso-, escribir
SetComplete si UpdateCoso fue bien o SetAbort si UpdateCoso dió un
error y -last but not least- haber hecho el Set X=Nothing a la
instancia que acabamos de usar.

Y como dije antes, si bien eso de que las variables "Global" -tal como
hemos aprendido- deben evitarse y su uso puede ser visto como un
problema, también puede ser una solución cuando queremos o necesitamos
que exista un lugar común (la variable global) donde los valores se
estén actualizando todo el tiempo (lo cual puede venir muy bien para
-por ejemplo- hacer un monitoreo de actividad "real time" sin
necesidad de estar grabando y leyendo de la BD o de otro lado).

Hasta ahora eso es lo que yo tenía entendido, que esto pasa UNICAMENTE
con las dichosas variables GLOBALES.

Sin embargo, recientemente otro colega discrepaba conmigo afirmando
que TAMBIEN LAS VARIABLES PUBLICAS Y PRIVADAS de las clases son
afectadas por este mismo "problema" de "volatibilidad", con lo que su
estilo de programación en tres capas corriendo en COM+ se resumía
únicamente a que en las clases de las capas (no en la interfaz de
usuario) escribía SOLAMENTE METODOS (Subs y Functions), o sea nada de
variables públicas ni privadas (incluso ni properties, ya que en el
99% de los casos esos métodos se usan para escribir o leer "desde
afuera" valores en/desde variables privadas de la clase).

Yo por supuesto discrepé desde un principio dado QUE NO IMAGINO TAL
VIOLACION DEL ENCAPSULAMIENTO, que es la única característica "object
oriented" de Visual Basic 6 (o una de las muy pocas), lo cual
convertiría a las clases en simples repositorios de métodos donde por
parámetros habría que pasar absolutamente todo y no se podría declarar
ni una sola variable a nivel de la clase -ni pública ni privada- a
riesgo de que corriendo en COM+ no habría ninguna garantía de que el
valor en dicha variable fuera el mismo en la siguiente línea de
código.

En mi opinión, y al mismo tiempo pidendo la opinión de alguien que se
anime a meter la cuchara, tanto las variables públicas como privadas
de las clases están resguardadas de "volatilización" siempre y cuando
uno
cree y use el objeto que corre en COM+ "en un contexto", con un código
más o menos como el ejemplo a continuación (un método en la capa de
"BusinessRules" que llama a otro en la capa de "DataTranslation"):



Public mbVacíoExistencial As Boolean
'variable declarada en el módulo de
'clase BR "visible" para quien use esta clase

Private msComentario As String
'variable declarada en el módulo de clase BR
'"sólo visible" a nivel de esta clase


Public Function BRgetInfo(ByVal sCodigo As String, _
ByVal sValor As String, _
ByRef vRecordSet As ADOEB.RecordSet, _
) As Boolean

On Error GoTo catch

Dim oContext As ObjectContext

BRgetInfo = False

Set oContext = GetObjectContext()

If Not oContext Is Nothing Then
Set DT = oContext.CreateInstance(DataTranslation_clsDT)
Else
Set DT = New DataTranslation.clsDT
End If

DT.GetData sCodigo, sValor, vRecordSet
mbVacíoExistencial = DT.lRegistrosLeídos = 0
If mbVacíoExistencial Then
msComentario = "Parece que no hay información al respecto".
Else
msComentario = "OK, " & DT.lRegistrosLeídos & " resultados."
Endif

Set DT = Nothing

SendComentario msComentario

If Not oContext Is Nothing Then oContext.SetComplete
Set oContext = Nothing

BRgetInfo = True

Exit Function

catch:
If Not oContext Is Nothing Then oContext.SetAbort
Set oContext = Nothing
TratamientoDeError "BRgetInfo"
End Function



Viendo este código mi colega afirmaba tres cosas:
1) que NO HAY GARANTÍA de que la variable pública lRegistrosLeídos del
objeto en la capa DT contenga 0 si efectivamente mi consulta no
devolvió ningún registro.
2) que NO HAY GARANTÍA para el que está llamando a esta clase BR de
que la variable pública mbVacíoExistencial contenga True si
efectivamente mi consulta no devolvió ningún registro, y
3) que NO HAY GARANTÍA de que el método SendComentario envíe el
comentario correcto (para algún lado, esto acá es un ejemplo nada
más).

Su argumento es que el valor en la variable pública lRegistrosLeídos
de la DT "se volatiliza porque no se sabe con qué instancia de DT
estamos trabajando línea a línea de código" cuando DT corre en COM+.
Y también argumenta que tanto el valor de la variable pública
mbVacíoexistencial de la BR como incluso el valor de LA VARIABLE
PRIVADA msComentario de la BR "se volatilizan" para el que llama a la
BR cuando ésta corre en COM+.

Mi argumento es que no debería pasar eso SIEMPRE Y CUANDO se usen las
variables (de la clase llamada) DENTRO DEL CONTEXTO, es decir después
de ser creado el objeto (obviamente) con GetObjectContext y antes de
ejecutar SetComplete o SetAbort según sea el caso (ok o error), con lo
que queda preservado (siempre cuidando de respetar estas reglas) el
principio de encapsulamiento.

Gracias.
As Zamt.
 

Leer las respuestas

#1 azimut
23/07/2003 - 07:40 | Informe spam
(As Zamt) wrote in message news:...
Hola, quisiera saber alguna opinión respecto a un asunto sobre
variables en módulos de clases Visual Basic 6 corriendo en COM+.




Nadie sabe ?

Preguntas similares