¿Cómo organiza su marco MVC mientras admite módulos / complementos? [cerrado]

17

Hay dos estructuras principales de base de código que he visto cuando se trata de marcos MVC. El problema es que ambos parecen tener un error organizacional que los acompaña.

MVC estándar

/controller
/model
/view

Problema: no hay separación de componentes relacionados (foro, blog, usuario, etc.)

MVC modular

/blog
    /controller
    /model
    /view
/user
    /controller
    /model
    /view
/forum
    /controller
    /model
    /view

Elegir el sistema basado en módulos te deja con un problema.

  • Nombres largos (Forum_Model_Forum = forum / model / forum.php) (como Zend)
  • ¿El sistema de archivos busca utilizando is_file()para encontrar qué carpeta tiene el modelo de foro? (Como Kohana)

¿Hay alguna otra estructura MVC que funcione bien cuando se trata de separar diferentes módulos? ¿Hay beneficios de estas estructuras que me faltan?

Xeoncross
fuente
1
También me gustaría agregar que quiero una estructura que sea compatible con PSR-0 para que también pueda usar bibliotecas como Zend y Doctrine si es necesario.
Xeoncross

Respuestas:

9

Tratar:

/blog 
    /controller
    /view
/user
   /controller
    /view 
/forum
    /controller
    /view
/model
    User
    BlogPost
    Comment
    ....

Sus modelos son el corazón de su aplicación. Debe diseñarlos y codificarlos como un paquete independiente. Los controladores son solo clientes de su modelo, que pasan a traducir la actividad del usuario en acciones para su modelo. Una vista es solo una forma particular de mostrar datos de su modelo. Si su aplicación crece, podría ir aún más lejos al separar a los clientes del modelo:

WebClient
    /blog 
        /controller
        /view
    /user
       /controller
        /view 
    /forum
        /controller
        /view
CommandLineClient
    delete_spam_posts_script
RestApiClient

/model
    User
    BlogPost
    Comment
    ....

Esto debería hacer obvio que puede tener múltiples clientes, que todos de una forma u otra, interactúan con un solo modelo.

Mathias Verraes
fuente
+1 porque estoy totalmente de acuerdo con tu explicación de los componentes MVC y cómo deberían funcionar. Sin embargo, el objetivo de un módulo es que puede importar módulos creados por otros usuarios, por lo que tener los modelos fuera de la ruta del módulo lo hace menos "arrastrar y soltar". Sin embargo, su método tiene mucho sentido para las aplicaciones que no utilizan complementos o módulos externos.
Xeoncross
@Xeoncross es cierto, realmente no he tenido en cuenta la reutilización aquí. Si ese es un requisito, podría ir un paso más allá y tener, por ejemplo, un módulo 'Usuario' que agrupe el modelo de Usuario con su controlador, y un módulo Blog que agrupe el modelo BlogPost y Comment con sus controladores. Como siempre: depende del contexto :-)
Mathias Verraes
2

;)

Encontré la mejor estructura para un Marco MVC / HMVC combinado. Para lo principal, necesita usar controladores / modelos / vistas base ... pero para los componentes individuales de los módulos del curso ...

Entonces, en mi estructura de marco MVC / HMVC se ve así:

/application
  controllers/
  models/
  views/
  modules/
    blog/
      controllers/
      models/
      views/ 
    user/
      controllers/
      models/
      views/
    forum/
      controllers/
      models/
      views/

Además, si lo necesito, agrego módulos de bibliotecas, i18n o helpers.

La convención de nomenclatura es fácil, para los controladores y modelos agrego el sufijo _Controller y _Model. Para los controladores y modelos de los módulos, también agrego un prefijo con el nombre del módulo, por ej. El perfil del controlador en el módulo Usuario se denominará User_Profile_Controller.

Por lo tanto, es muy fácil y rápido encontrar lo que necesita.

Shogun
fuente
1

Problema: nombres largos (Forum_Model_Forum)

El nombramiento sistemático de las clases ayuda a evitar conflictos de nombres entre componentes. El nombramiento prolongado de clases no es probable que imponga sanciones severas de rendimiento. Encuentro este esquema de nombres bastante útil cuando se codifica porque es fácil ver de dónde viene.

búsquedas en el sistema de archivos (¿qué carpeta tiene el modelo de foro?).

Esto depende en gran medida de cómo se haya implementado el sistema, pero la estructura del sistema de archivos generalmente sigue una convención que permite el acceso inmediato al componente correcto sin búsquedas exhaustivas del sistema de archivos.

Aquí hay un ejemplo, supongamos que se va a utilizar el componente del foro:

Información:

  • Nombre del componente: foro
  • Nombre del controlador: índice

    $ controller_path = BASEDIR. 'módulo /'. $ nombre_componente. '/controlador/' . $ nombre_controlador. '.php';

También es importante tener en cuenta que hay literalmente cientos de consultas del sistema de archivos al iniciar un sitio web típico, por lo que agregar algunas no va a dañar.

Lea Hayes
fuente
Verdaderamente, los servicios de fondo no son como las aplicaciones del lado del cliente que necesitan iniciarse rápidamente, pueden tomar el tiempo necesario para configurar el tiempo de ejecución correctamente. Buen punto.
Patrick Hughes
0

Tengo trabajo con sitios web que comenzaron con el primer "MVC estándar", pero eventualmente se convirtieron en el "MVC modular".

Si está haciendo un sitio web pequeño y no tiene mucha experiencia, puede comenzar con el "MVC estándar". Si ya sabe que el sitio web va a ser muy complejo y grande, entonces tendrá que acostumbrarse al "MVC Modular", será un poco difícil al comienzo, pero, eventualmente, se acostumbrará a eso.

umlcat
fuente
0

De hecho, estoy trabajando en un marco y utilizo una combinación de estructura de directorios basada en módulos y de forma libre. Mi estructura predeterminada para el código del sitio que usa el marco es:

/Configuration (stored a bunch ini files for security related information like passwords)
/Functions (stores file(s) with standard procedural functions)
/Libraries (general use classes)
/Models (all models go here)
/Modules (each module refers to one controller
/Modules/Site (controller class store in this folder if there is a controller)
/Modules/Site/Views (views for the controller)

También puede tener una carpeta de módulo que no se relacione con un controlador y hay una llamada Core por defecto que se usa para almacenar plantillas de todo el sitio como el encabezado y el pie de página. Esto para mí da lo mejor de ambos mundos. Puede saber fácilmente dónde está el controlador, ya que hay un controlador por carpeta, pero para clases como modelos no necesita buscar dónde están los archivos, ya que están en un directorio (que también mantiene los nombres de los modelos más limpios) .

La forma en que cargo los archivos es un poco diferente, ya que le permito al usuario configurar los diferentes directorios sobre dónde podrían estar las clases, así que analizo los directorios inicialmente y almaceno todas las ubicaciones de los archivos de clase en un archivo json y luego lo uso para buscar rápidamente todas las demás solicitudes (aunque estoy buscando formas de mejorar esto).

ryanzec
fuente
0

La respuesta a esto ha sido dictada por la Propuesta PSR-0 que todos los sistemas grandes están comenzando a adaptarse, o que han adoptado ahora.

La estructura es:

\Doctrine\Common\IsolatedClassLoader => /Doctrine/Common/IsolatedClassLoader.php
\Symfony\Core\Request => /Symfony/Core/Request.php
\Zend\Acl => /Zend/Acl.php
\Zend\Mail\Message => /Zend/Mail/Message.php

Esto significa que no hay nada que pueda hacer para arreglar nombres largos de archivos:

$controller = new \Blog\Controller\Archive => /Blog/Controller/Archive.php

/Blog
    /Controller
        Archive.php
    /Model
    /View
/User
    /Controller
    /Model
    /View
/Forum
    /Controller
    /Model
    /View

Esto también significa que debe usar archivos tontos de mayúsculas y minúsculas en lugar de todas las minúsculas (si no lo hace, las bibliotecas de terceros no funcionarán).

Xeoncross
fuente
0

La solución de Mathiases tiene mucho sentido. Y el uso de su estructura de carpetas no impide tener contenido conectable, por ejemplo, agregar un / galería / independiente podría verse así

WebClient
    /blog 
        /controller
        /view
    /user (uses /model/User/)
       /controller
        /view 
    /forum
        /controller
        /view
    /gallery
        /controller
        /view
        /model
CommandLineClient
    delete_spam_posts_script
RestApiClient

/model
    User
    BlogPost
    Comment

Ahora tenemos un "modelo" compartido e independientes si es necesario

Timo Huovinen
fuente