Clipper/FiveWin - Modelo 3 capas en Xbase

 
Vista:

Modelo 3 capas en Xbase

Publicado por Juanato (19 intervenciones) el 16/08/2008 10:23:43
Bueno, sabreis que hoy dia, el que no programe en tres capas, no es nadie. Yo sin saber lo que eran las tres capas, ya en 1995 me tuve que buscar la vida para hacer más sencillo el mantenimiento de los ficheros xbase, ya que Ca Clipper permitia un buen data driven, y se podian hacer las cosas mejor que en Foxpro. Así que me puse a la labor, pero dejando de lado los diccionarios de datos autodescritos, y se me ocurrió la feliz idea, de segun el orden de los campos en cada tabla xbase, nunca me encontraria el memo ni un binario largo si existiese, al principio, para que éste fuse el delimitador de la estructura a pasar a un array. Así, en tiempo de ejecución, el diccionario de datos sera la estructura de la tabla, omitiendo memos y demás....

Así creé estas primitivas:


// AinitFields()
function AinitFields()
local nI := 1
local aDbfStr := {}
local aValLocal := {}
aDbfStr := DbStruct()
For nI = 1 to Len( aDbfStr )
cType := aDbfStr[nI][2]
nLen := aDbfStr[nI][3]
Aadd( aValLocal, FieldInit( cType, nLen ) )
Next
return( aValLocal )

// FieldInit( cType, nLen )
function FieldInit( cType, nLen )
local xVar
Do Case
Case cType == 'A'
xVar := {}
Case cType == 'C'
xVar := Replicate( chr(255), nLen )
Case cType == 'D'
xVar := Date()
Case cType == 'L'
xVar := .f.
Case cType == 'M'
xVar := space(1)
Case cType == 'N'
xVar := 0
Case cType == 'U'
Alert('Un campo mal Definido !!!')
xVar := nil
EndCase
return xVar

// Ainit( aArray )
function Ainit( aArray )
local nI := 1
for nI = 1 to Len( aArray )
aArray[ nI ] := VarInit( aArray [ nI ] )
next
return aArray

// VarInit( xVar )
function VarInit( xVar )
Do Case
Case ValType(xVar) == 'A'
xVar := {}
Case ValType(xVar) == 'B'
xVar := { || Cls() }
Case ValType(xVar) == 'C'
xVar := Replicate( space(1), Len( xVar) )
Case ValType(xVar) == 'D'
xVar := Date()
Case ValType(xVar) == 'L'
xVar := .f.
Case ValType(xVar) == 'M'
xVar := space(4096)
Case ValType(xVar) == 'N'
xVar := 0
Case ValType(xVar) == 'O'
xVar := {}
Case ValType(xVar) == 'U'
xVar := nil
EndCase
return xVar


y las uso en el código así: ESte es un ejemplo de mantenimiento de un maestro de clientes

function CliMaeMng( lExit, cNifCli )
local GetList := {} ,;
nI := 0 ,;
nCursor := SetCursor()

local aBox01 := BoxOpen( 2, 2, 19, 68, 'úMantenimiento Clientesú', aClr[10])

// Salida del BUCLE, una ALTA externa !! ( ess para hacer mantenimiento predictivo)
DEFAULT lExit := .f.
DEFAULT cNifCli := space(10)

// Lectura Estructura DBF y crear MASCARA, sin longitud definida
aValFields := {}
aValFields := climae->( AinitFields( ) ) // Carga CAMPOS perfil

aSN := {'Si', 'No'}
aSexo := {'Var¢n', 'Mujer',' '}
do while .t.

nOP := 0

// Inicializa ARRAY a valores seg£n naturaleza...
aValFields := aInit( aValFields ) // Inicializa campos

SetCursor(1)

aSN := {'Si', 'No'}
nOP := 0
cOldScr := space(4000)

ScrCliMae() // M scara de Captura
StatusMsg('Mantenimiento de CLIENTES Gestor¡a')
climae->( OrdSetFocus(1) )
climae->( DbGoBottom( ) ) // Primer Recno
if empty( cNifCli )
aValFields[1] := climae->C01 // Facilitamos que sepa el operador ultimo código dado de alta
Else
aValFields[1] := cNifCli // hemos llamado desde otro procedimiento al mantenimiento....
EndIf

@ 04, 22 GET aValFields[1] ;
PICT '@!' ;
COLOR aClr[2] ;
CAPTION '&Cif/Nif Cliente ' ;
MESSAGE 'Introduzca CIF/DNI/ NIF del CLIENTE, deje en BLANCO para Consulta'

READ MSG AT MaxRow()-1, 0, MaxCol() MSG COLOR 'w+/B'
/*
If Len(AllTrim(aValFields[1])) < 8 .and. ! Empty(aValFields[1])
Alert('Longitud DNI Incorrecta,;'+;
'O el CIF no est COMPLETO,;'+;
'Intentelo de NUEVO' )
loop // Volver a EMPEZAR
EndIf
*/
aValFields[1] := ValidDNI( aValFields[1]) // Comprobaci¢n DNI
@ 04, 22 SAY aValFields[1] COLOR aCLr[1]
if LastKey() = K_ESC // V monos de aqu¡
exit
endif

if Empty( aValFields[1]) // Consulta

@ 06, 22 GET aValFields[3] PICT '@!' ;
COLOR aClr[2] ;
CAPTION '&Apellido 1§.... ' ;
MESSAGE 'Introduzca Apellido 1§ del CLIENTE'

READ MSG AT MaxRow()-1, 0, MaxCol() MSG COLOR 'w+/BG'
climae->( OrdSetFocus(2))
If ! Empty( aValFields[3])
climae->( DbSeek( aValFields[3], .t.) )
EndIf

climae->( Tabla( .f., 4, 4, 17, 60,;
{ 'Apellido 1§','Apellido 2§','NIF/CIF' },;
{'C03','C04', 'C01' }, .f. ) )

cNifCli := climae->C01

Loop
EndIf

climae->( OrdSetFocus(1)) // C¢digo
climae->( DbGoTop() )
if climae->( DbSeek( aValFields[1], !lSoftSeek ))
ConCliMae( climae->( DbRLock() ) )
Else
AltCliMae( aValFields ) // Altas de Clientes
EndIf

If lExit
exit
EndIf

enddo
SetCursor( nCursor )
BoxClose( aBox01 )
return


Visto el código anterior, no es fácil darse cuenta de lo que es el mantenimiento predictivo, basado en la clave primaria, algo que los programadores de Visualbasic del estilo juanpedropiñonero no se enteran ni a la de trés... mi pregunta es... cuántos de vosotros programais en un modelo parecido a éste.. donde os despreocupeis de las estructura de datos en disco, solo os preocupen las copias en memoria de los registros candidatos con los que trabajais, y por último, el data driven lo lleveis a la máxima expresió con el denominado MANTENIMIENTO PREDICTIVO ?

Lo digo, porque seria interesante una contribución a xharbour/xailer/fivewin que contase con las especificaciones, al igual que lo revolucionario que fue la notación húngara, de tener un modelo de 3 capas sencillo, ya se use LETODB, RDD local, ODBC o lo que sea...


¿ Quien se anima a contar lo que tiene de modelo de 3 capas ?


Sabeis que los programadores .NEt son tan torpes, que el la capa de negocio no manejan arrays como imagen del registro candidato, sino que lo implementan en la capa cliente-servidor, con lo cual redundan código, y a pesar que programa en oop extreme, no les srive de mucho, porque repiten los mismo métodos en clases orientadas a manejo de tablas en un nivel inferior a la capa de negocio, con lo cual necesitan instanciar siempre objetos que llevan métodos solo para esa tabla, y se olvidan de que el mismo código está repetido en todas las tablas ? Si usasen unobjeto para guardar el registro activo en un array y manejarlo, hasta que como candidato deba pasar a la capa servidor para actualizar, se ahorrarian código.... quien sabe de lo que estoy escribiendo ?
Valora esta pregunta
Me gusta: Está pregunta es útil y esta claraNo me gusta: Está pregunta no esta clara o no es útil
0
Responder