Saludos
Existe algun ejemplo de como aplicar el MVC en Fivewin?
FWH 25.12
Harbour/Hbmk2
Microsoft Visual C++
MySql 8.0
Antigravity
Saludos
Existe algun ejemplo de como aplicar el MVC en Fivewin?
FWH 25.12
Harbour/Hbmk2
Microsoft Visual C++
MySql 8.0
Antigravity
+ codigo
+--- controlador
+--- modelo
+--- vistafunction Control_Clientes( cOpcion )
case 'Cargar' ; Cargar()
case 'Salvar' ; Salvar()
...Function Cargar()
oCliente := TCliente():New()
return oCliente->Load()+ codigo
+--- controlador
+--- cclientes.prg
+--- modelo
+--- mclientes.prg
+--- vista
+--- vclientes.prg/*
* Proyecto: PruebaMVC
* Fichero: P00.prg
* Descripción: Ejemplo modo texto de las clases.
* Autor: Manu Exposito Suárez
* Fecha: 20/09/2011
* Version: 0.12
*/
//-----------------------------------------------------------------------------
#include "hbclass.ch"
//-----------------------------------------------------------------------------
REQUEST HB_GT_WIN
//-----------------------------------------------------------------------------
// Programa principal de la prueba
FUNCTION main()
LOCAL oPrg := Programa():new()
cls
@ 01, 10 SAY "Ejemplo del patron Modelo Vista Controlador"
oPrg:ejecuta()
RETURN nil
//-----------------------------------------------------------------------------
// Clase principal para el ejemplo de pruebas etc
CLASS Programa
DATA control
METHOD new() CONSTRUCTOR
METHOD ejecuta()
ENDCLASS
//-----------------------------------------------------------------------------
METHOD new() CLASS Programa
::control := ControlConversor():new( VistaTXT():new(), ;
ConversorEurosPesetas():new() )
RETURN self
//-----------------------------------------------------------------------------
METHOD ejecuta() CLASS Programa
::control:getVista():arranca()
RETURN nil
//-----------------------------------------------------------------------------//---------------------------------------------------------------------------//
// AUTOR.....: Manuel Expósito Suárez Soft4U 2002-2011 //
// CLASE.....: MVC - Vista - InterfazVista //
// FECHA MOD.: 20/11/2011 //
// VERSION...: 1.00 //
// PROPOSITO.: Ejemplo de Modelo Vista Controlador //
//---------------------------------------------------------------------------//
#include "HbClass.ch"
//-----------------------------------------------------------------------------
// Vista 1/2
// Clase para Abstracta para la creacion de vistas.
// En las clases derivadas hay que implementar al menos estos 4 metodos
CREATE CLASS InterfazVista
PROTECTED:
DATA controlador
DATA tipoConversion // "Pesetas a Euros" -> 0 "Euros a Pesetas" -> 1
EXPORTED:
// Se implementan en cada vista
METHOD arranca() VIRTUAL
METHOD getCantidad() VIRTUAL
METHOD escribeCambio( s ) VIRTUAL
// SET GET
METHOD setControlador( oControlador )
METHOD getControlador()
METHOD setTipoConversion( nTipo )
METHOD getTipoConversion()
ENDCLASS
//-----------------------------------------------------------------------------
// Asigna el tipo Conversion
METHOD setTipoConversion( nTipo ) CLASS InterfazVista
LOCAL ret := ::tipoConversion
IF ValType( nTipo ) == "N" .and. ( nTipo == 0 .or. nTipo == 1 )
::tipoConversion := nTipo
END IF
RETURN ret
//-----------------------------------------------------------------------------
// Obtiene el tipo Conversion
METHOD getTipoConversion() CLASS InterfazVista
RETURN ::tipoConversion
//-----------------------------------------------------------------------------
// Asigna el controlador
METHOD setControlador( oControlador ) CLASS InterfazVista
LOCAL ret := ::controlador
IF ValType( oControlador ) == "O"
::controlador := oControlador
END IF
RETURN ret
//-----------------------------------------------------------------------------
// Obtiene el tipo controlador
METHOD getControlador() CLASS InterfazVista
RETURN ::controlador
//-----------------------------------------------------------------------------//---------------------------------------------------------------------------//
// AUTOR.....: Manuel Expósito Suárez Soft4U 2002-2011 //
// CLASE.....: MVC - Vista - VistaTXT //
// FECHA MOD.: 20/11/2011 //
// VERSION...: 1.00 //
// PROPOSITO.: Ejemplo de Modelo Vista Controlador //
//---------------------------------------------------------------------------//
#include "HbClass.ch"
//-----------------------------------------------------------------------------
// Vista 2/2
CREATE CLASS VistaTXT FROM InterfazVista
PROTECTED:
METHOD leeOpcion()
METHOD leeCantidad()
METHOD solicitaOperacion()
METHOD procesaNuevaOperacion()
METHOD operacionIncorrecta()
EXPORTED:
METHOD new() CONSTRUCTOR
// Implementacion de los metodos de la interfaz vista
METHOD arranca()
METHOD escribeCambio()
METHOD getCantidad()
ENDCLASS
//-----------------------------------------------------------------------------
// Constructor
METHOD new( oControlador ) CLASS VistaTXT
IF ValType( oControlador ) == "O"
::controlador := oControlador
END IF
RETURN Self
//-----------------------------------------------------------------------------
// Pone en marcha la vista
METHOD arranca() CLASS VistaTXT
::procesaNuevaOperacion()
RETURN nil
//-----------------------------------------------------------------------------
// Se encarga de sacar por pantalla la informacion
METHOD escribeCambio( s ) CLASS VistaTXT
CLS
?
?
? "Resultado --->", s
?
?
::procesaNuevaOperacion()
RETURN nil
//-----------------------------------------------------------------------------
// Obtiene la cantidad
METHOD getCantidad() CLASS VistaTXT
RETURN ::leeCantidad()
//-----------------------------------------------------------------------------
METHOD leeOpcion() CLASS VistaTXT
LOCAL cOpcion := " "
LOCAL getList := {}
@ row() + 1, col() SAY "Elige opcion:" GET cOpcion
READ
cOpcion := AllTrim( cOpcion )
IF !( cOpcion $ " 0 1 2 " )
::operacionIncorrecta()
END IF
RETURN cOpcion
//-----------------------------------------------------------------------------
METHOD leeCantidad() CLASS VistaTXT
LOCAL nCantidad := 0
LOCAL getList := {}
@ row(), col() SAY "Cantidad:" GET nCantidad
READ
RETURN nCantidad
//-----------------------------------------------------------------------------
METHOD solicitaOperacion() CLASS VistaTXT
? "----------------------------------------------------------------------"
? "Indical operacion que quieres realizar:"
? "---------------------------------------"
?
? "1 Pesetas a euros"
? "2 Euros a pesetas"
? "0 Salir"
?
?
RETURN nil
//-----------------------------------------------------------------------------
METHOD procesaNuevaOperacion() CLASS VistaTXT
::solicitaOperacion()
SWITCH ::leeOpcion()
CASE '0'
?
? "Adios"
?
quit
CASE '1'
::setTipoConversion( 0 )
::controlador:gestionDeAcciones()
EXIT
CASE '2'
::setTipoConversion( 1 )
::controlador:gestionDeAcciones()
EXIT
//DEFAULT
OTHERWISE
::operacionIncorrecta()
END SWITCH
RETURN nil
//-----------------------------------------------------------------------------
METHOD operacionIncorrecta() CLASS VistaTXT
?
? "Valor incorrecto..."
?
InKey( 5 )
cls
::procesaNuevaOperacion()
RETURN nil
//-----------------------------------------------------------------------------//---------------------------------------------------------------------------//
// AUTOR.....: Manuel Expósito Suárez Soft4U 2002-2011 //
// CLASE.....: MVC - Modelo - ConversorEuros //
// FECHA MOD.: 20/11/2011 //
// VERSION...: 1.00 //
// PROPOSITO.: Ejemplo de Modelo Vista Controlador //
//---------------------------------------------------------------------------//
#include "HbClass.ch"
//-----------------------------------------------------------------------------
// Modelo 1/2
// Clase para convertis cualquier moneda a Euros
CREATE CLASS ConversorEuros
PROTECTED:
DATA cambio
EXPORTED:
METHOD new( valorCambio ) CONSTRUCTOR
METHOD eurosAMoneda( cantidad )
METHOD monedaAEuros( cantidad )
// SET GET
METHOD setCambio( cambio )
METHOD getCambio()
ENDCLASS
//-----------------------------------------------------------------------------
// Constructor
METHOD new( valorCambio ) CLASS ConversorEuros
IF ValType( valorCambio ) == "N"
::cambio := valorCambio
ENDIF
RETURN Self
//-----------------------------------------------------------------------------
// Pasa euros a la moneda
METHOD eurosAMoneda( cantidad ) CLASS ConversorEuros
RETURN IF( ValType( cantidad ) == "N", cantidad * ::cambio, 0 )
//-----------------------------------------------------------------------------
// Pasa las monedas a euros
METHOD monedaAEuros( cantidad ) CLASS ConversorEuros
RETURN IF( ValType( cantidad ) == "N", cantidad / ::cambio, 0 )
//-----------------------------------------------------------------------------
// Asigna el cambio
METHOD setCambio( cambio ) CLASS ConversorEuros
LOCAL ret := ::cambio
IF ValType( cambio ) == "N"
::cambio := cambio
END IF
RETURN ret
//-----------------------------------------------------------------------------
// Obtiene el cambio
METHOD getCambio() CLASS ConversorEuros
RETURN ::cambio
//-----------------------------------------------------------------------------//---------------------------------------------------------------------------//
// AUTOR.....: Manuel Expósito Suárez Soft4U 2002-2011 //
// CLASE.....: MVC - Modelo - ConversorEurosPesetas //
// FECHA MOD.: 20/11/2011 //
// VERSION...: 1.00 //
// PROPOSITO.: Ejemplo de Modelo Vista Controlador //
//---------------------------------------------------------------------------//
#include "HbClass.ch"
//-----------------------------------------------------------------------------
// Modelo 2/2
// Clase para convertir pesetas a Euros
CREATE CLASS ConversorEurosPesetas FROM ConversorEuros
METHOD new() CONSTRUCTOR
ENDCLASS
//-----------------------------------------------------------------------------
// Constructor
METHOD new() CLASS ConversorEurosPesetas
::setCambio( 166.386 )
RETURN Self
//-----------------------------------------------------------------------------//---------------------------------------------------------------------------//
// AUTOR.....: Manuel Expósito Suárez Soft4U 2002-2011 //
// CLASE.....: MVC - Controlador - ControlConversor //
// FECHA MOD.: 20/11/2011 //
// VERSION...: 1.00 //
// PROPOSITO.: Ejemplo de Modelo Vista Controlador //
//---------------------------------------------------------------------------//
/*
El CONTROLADOR
Desde aqui se reciben las peticiones del usuario a travez de la VISTA y se
trasladan al MODELO
*/
#include "HbClass.ch"
//-----------------------------------------------------------------------------
// Control 1/1
CREATE CLASS ControlConversor
PROTECTED:
DATA vista
DATA modelo
EXPORTED:
METHOD new( vista, modelo ) CONSTRUCTOR
METHOD gestionDeAcciones( cTipo )
METHOD getVista()
METHOD setVista( vista )
METHOD getModelo()
METHOD setModelo( modelo )
ENDCLASS
//-----------------------------------------------------------------------------
// Constructor
METHOD new( vista, modelo ) CLASS ControlConversor
::vista := vista
::modelo := modelo
::vista:setControlador( Self )
RETURN self
//-----------------------------------------------------------------------------
// Control de acciones
METHOD gestionDeAcciones() CLASS ControlConversor
LOCAL cantidad := ::vista:getCantidad()
IF ::vista:getTipoConversion() == 0
::vista:escribeCambio( AllTrim( str( cantidad ) ) + " pesetas son: " + ;
AllTrim( str( ::modelo:monedaAEuros( cantidad ) ) ) + " euros" )
ELSEIF ::vista:getTipoConversion() == 1
::vista:escribeCambio( AllTrim( str( cantidad ) ) + " euros son: " + ;
AllTrim( str( ::modelo:eurosAMoneda( cantidad ) ) ) + " pesetas" )
ELSE
::vista:escribeCambio( "ERROR" )
END IF
RETURN nil
//-----------------------------------------------------------------------------
// Obtiene la vista
METHOD getVista() CLASS ControlConversor
RETURN ::vista
//-----------------------------------------------------------------------------
// Asigna la vista
METHOD setVista( vista ) CLASS ControlConversor
::vista := vista
RETURN nil
//-----------------------------------------------------------------------------
// Obtiene el modelo
METHOD getModelo() CLASS ControlConversor
RETURN ::modelo
//-----------------------------------------------------------------------------
// Asigna el modelo
METHOD setModelo( modelo ) CLASS ControlConversor
::modelo := modelo
RETURN nil
//-----------------------------------------------------------------------------Manu,
interesante ejemplo, sobre el cual me permito hacer alguna observación:
Tu controlador tiene cosas como AllTrim( str( cantidad ) ) + " pesetas son: " + AllTrim( str( ::modelo:monedaAEuros( cantidad ) ) ) + " euros" , que es parte de la VISTA. Se demuestra si tratamos de traducir la app a otro idioma, tendríamos que cambiar el controlador, lo que se supone que si está bien no debería suceder.
El patrón MVC define Modelo, Vista y Controlador, pero si queremos un framework completo, la arquitectura necesita de más aditamentos: un router que mueve los mensajes, una petición (o request) una respuesta ( o response), y más cacharros que 'aceitan' los engranajes. Es una forma no muy lineal que cuesta alinearla con el modelo mental que automaticamente usamos cundo programamos en Harbour clásico.
Tu vista tiene un método GetCantidad, GetTipoConversion que estarían en la request. En realidad existirían 2 clases de request: la RequestEuroToPesetas y otra RequestPesetaAEuro, la vista genera los eventos de forma apropiada creando una u otra request. El controlador la recibe y en un case le pasará el mensaje apropiado al Modelo, que hará la conversión, creará una nueva response que se enviará a la vista correspondiente.
Es característico que los controladores tiende a ser muy pequeños, de muy poquitas líneas, porque solo dirigen el tráfico, no alteran ni solicitud ni respuesta, solo invocan modelos y vistas. Lo gordo suele estar del lado del modelo, donde se encuentan frecuentemente, para cada objeto, una clase Repositorio y una clase Entidad. En la clase repositorio estarían los métodos que afectan al conjunto de entidades: por ejemplo en el repositorio FacturasRepo habría un método TodasDeCliente( cCodCliente ) que devolvería una colección de objetos EntidadFactura, aquellas que corresponden a un determinado cliente. En cambio la clase EntidadFactura tendría métodos tipo EstaVencida() ( boolean ) o TotalFactura() que afectan a un solo individuo o entidad.
Retomando el concepto de 'router', 'request' y 'response', estas clases son particulares de el entorno de la aplicacion: no es lo mismo un ruter de una app de escritorio, de una app web (como Fiveweb o FWeb).
Bueno, tengo que volver al curro, pero... pufff da para muchísimo.
El Rafa subió en algun momento un ejemplo de una aplicacion web escrita en Harbour usando el http server de Harbour. Si adaptas tu código para que responda usando la estructura de esa aplicacion el panorama se aclara muchísimo.
Un saludo
Cuánta razón tienes Carlos!!!
Esto era una aproximación, lo importante era crear el debate a partir de la entrada de Compuin. Básicamente porque me interesa muchísimo.
EL MVC se aplica perfectamente en aplicaciones web ya que el concepto de enrutador y request y response (con GET o POST) están muy bien definidos.
La propuesta que hago es que a partir de lo que hay se implemente lo que falta o se mejore lo ya expuesto... quien se anima?
![]()
![]()
Excelente debate!
Cada punto de vista aporta conocimiento y entre todos aprendemos
FWH 25.12
Harbour/Hbmk2
Microsoft Visual C++
MySql 8.0
Antigravity