En el foro de Fivetech lo puse, pero alguien me borró el usuario

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 ?
Betas y demas stuff:
http://www.4shared.com/dir/4925583/d558 ... aring.html