Ver Mensaje Individual
  #1 (permalink)  
Antiguo 01/06/2006, 01:47
Avatar de Hereje
Hereje
 
Fecha de Ingreso: junio-2002
Ubicación: Córdoba, Argentina
Mensajes: 439
Antigüedad: 21 años, 11 meses
Puntos: 2
Mi experimento MVC

Hola a todos! Nuevamente molestando, pero la verdad que esto de POO me genera tal incertidumbre (sobre si hago las cosas bien o mal) que no me deja dormir, debido a mi falta de teoria y experencia.

Antes debo aclarar que este experimento lo estoy desarrollando en PHP4, siendo conciente de los límites que esto conlleva. Digo experimento porque en verdad no tengo idea de lo que estoy haciendo, sólo la inercia me lleva para adelante con la esperanza que algo bueno puede salir de aquí (algo bueno podria ser saber que está todo mal ).

Empezando, les comento que estoy tratando de seguir las lineas de un patrón (no tengo muy claro el concepto de patrón) MVC. Para ello he definido la siguiente estructura de clases:

Aplicacion
Es la clase principal, se instancia por única vez en la página que hará de acceso al sistema. Se encarga (al crearse) de recojer las variables GET que indican el controlador (clase) que se instanciará, como así también la acción (método) que se llamará en una petición. Seguidamente y como paso final se hace dicha tarea (instanciar el controlador y llamar el método).

Controlador
Es la clase abstracta (no puedo creer que utilice esa palabra, antes de ayer he aprendido lo que significa) que sirve para dar las bases a las clases concretas de los controladores que se instanciarán. Por ahora, está compuesta por las siguientes clases (se instancian en propiedades públicas (no queda otra) en el constuctor del mismo):

UsuarioActual
Realiza una instacia del usuario que ha iniciado sesión en el sistema, sino hay, establece una propiedad para definir un usuario anónimo. Esta clase deberia ¿extender? a la clase Usuario del modelo, pero como esta última ¿extiende? a una clase abstracta Modelo y PHP4 no permite herencia múltiple, la clase UsuarioActual pasa a estar compuesta por una de Usuario. Luego de que esté creado este objeto, el controlador revisa (a través de un método del mismo) si el tipo de usuario tiene permisos suficientes como para acceder a éste.

Vista
Se encarga de imprimir la vista del controlador. Tiene propiedades como "disposicion" (vendria a ser el layout) y "plantilla" (la vista del controlador), entre otras, por ejemplo que son arrays de archivos css y js a incluir. El método más importante lo llamé "mostrar()", que hace eso mismo, y es llamado desde las acciones del controlador (en caso de ser necesario). Cuando se llama a este método, en caso de no haber establecido la propiedad "plantilla", buscará una plantilla con el mismo nombre del controlador (cosas de vagos, jeje). También dispone de un método que permite incluir las variables que se "pasaran" desde el controlador para mostrar en la plantilla.

Sessiones
Se encarga de "aislar" la administración de sessiones, por si mas adelante se las quiere administrar desde una bd, etc.

Fechas
Para manejar las fechas en GTM y luego aplicar diferencias horarios según configuraciones, etc.

Y otras clases de este tipo...

Modelo
Clase abstracta para dar base a las clases del modelo. Hace la conexión a la bd (instanciando otra clase, por ejemplo "Mysql", "Access", etc. indicada a partir de una constante en un archivo de configuración) y haciendo de "mascara" a la misma (¿A eso se le llama interfase?). Tiene métodos como "ejecutar(sql)", etc. También dispuse de un metodo llamado "usar" (que puede llamarse Metodo::usar('nombre_de_clase_modelo')) para incluir segun sea necesario los archivos de las clases de modelo. El id de la conexión lo puse en una variable global y la consulto en cada instancia para usar siempre la misma conexión.

Ayuditas
Esta clase no hace falta instanciarla, el objetivo de la misma es agrupar las funciones de "ayuda". Por ejemplo contiene funciones para utlizar tanto en el controlador (redirigir, validaciones, etc.) como para la vista (enlaces, grillas, etc.).

------------------------------------------------------------

Como les anticipé, esto es menjunje experimental. Prometo publicar código luego, pero antes quiero saber si está bien planteado. Algo que me llamó la atención es que me parece que abusé de la funcionalidad de los constructores, pues desde allí llamo a la mayoria de tareas que deben realizarse automaticamente. ¿Esto está bien o debo instanciar y luego llamar un método que haga estas tareas?

Otra cosa, tengo un archivo de configuración que se compone de definición de constantes. ¿Está bien o deberia crear una clase Config que tenga propiedades de las configuraciones del sistema de manera que todo sean objetos?

También veo que estas clases se instancian una sola vez. ¿Esta bien esto o conviene no hacer instancia de las mismas y utilizar sus funciones a través de "::"?

------------------------------------------------------------

Un ejemplo de como se ejecutaria una acción:

Una clase del modelo: Usuario.php
Código PHP:
<?php

class Usuario extends Modelo {

    var 
$nombre;

    function 
usuario($id) { parent::modelo();
    
        
$this->bd->ejecutar("select nombre from usuarios where id = '$id'");

        
$fila $this->bd->filas();
        
        
$this->nombre $fila['nombre'];
    }
    
    function 
getNombre() {
        return 
$this->nombre;
    }

    function 
guardar() {
        
//...
    
}

}

?>
Un controlador: MostrarNombreUsuario.php
Código PHP:
class MostrarNombreUsuario extends Controlador {

    function 
mostrarNombreUsuario() { parent::controlador(); }
    
    function 
inicial() {
        
        
Modelo::usar('usuario');
        
$usuario = new Usuario(1);
        
        
$this->vista->agregarVariable('nombre'$usuario->nombre);
        
$this->vista->mostrar();
        
    }


La vista: MostrarNombreUsuario/inicial.php
Código PHP:
<h2>Mostrar nombres</h2>

<p>El nombre del usuario es <?= $this->nombre ?></p>
---------------------------------------------------

Una url de ejemplo para ejecutar esto seria:
http://host/index.php?mod=MostrarNombreUsuario

Como no se especifica la acción a ejecutar del controlador, se busca la acción "inicial" por defecto, sino existe, tira error.

---------------------------------------------------

Generalmente no soy de escribir posts largos, asi que ya estoy medio perdido, pero en fin, esto es a grandes rasgos lo que hice. ¿Sirve? En caso que no esté todo absolutamente mal, ¿qué deberia corregir?. En caso que esté todo mal, ¿en qué le estoy errando?

También debo aclarar que he leido sobre RubyOnRails, el cual me ha dado la idea de como organizarme, como así también parte de la estructura de carpetas.

Muchas gracias a todos por vuestra atención, un abrazo!
__________________
Sergio