¿Por qué todos ponen controladores en una carpeta y vistas en otra?

36

Me estoy preparando para tomar la curva de asp y en un marco de mvc, asp.net mvc o nancy. Donde quiera que vaya, veo carpetas para controladores / módulos y carpetas para vistas. ¿Es esto solo un reflejo pavloviano de ordenar las cosas por tipo, o hay alguna sabiduría más profunda operando? Tengo un pequeño proyecto de prueba de concepto donde almaceno juntos los archivos que es probable que abra juntos, un consuelo considerable. Dado que es probable que estos archivos también se llamen entre sí, pueden hacerlo con enlaces relativos más cortos, menos frágiles. Este patrón es desafiado por mvc, porque la ruta de la carpeta ya no se corresponde automáticamente con la ruta de la url y, en asp.net mvc, las plantillas y el enrutamiento del proyecto imponen las vistas \ controladores \ cisma.

Esta página de Microsoft presenta el concepto de áreas. Puede leerse como una admisión de cuán difíciles de manejar se vuelven las aplicaciones grandes debido a esta separación artificial.

La gente objetará la "separación de preocupaciones", pero la separación de preocupaciones ya se logra al tener archivos fuente separados. Me parece que no hay ganancia concreta al tomar estos archivos de origen que están estrechamente acoplados y enviarlos a extremos opuestos de la estructura de carpetas.

¿Alguien más está luchando contra esto? ¿Algun consejo?

bbsimonbb
fuente
3
¿No cree que es lógico separar los archivos de código de fondo de los archivos de vista? Si ya estamos tomando la dirección, ¿por qué no colocar también los archivos CSS y JavaScript relevantes en la misma carpeta?
Alternatex
2
Si obtiene Resharper, entonces F12 en la llamada al Viewcontrolador lo lleva a la vista y la primera opción en el menú del botón derecho de la vista lo lleva al controlador, y todo el problema con la falta de navegación desaparece.
Pete Kirkham
44
@Alternatex Lo siento pero no veo cómo un controlador es "back-end". Está estrechamente acoplado a su (s) vista (s). La vista no sirve sin un controlador, el controlador no sirve sin la vista. Algún día querrás eliminarlos juntos. ¿Esa para mí es la mejor prueba de lo que pertenece en una carpeta? ¿A menos que alguien pueda mostrarme una mejor manera?
bbsimonbb
2
Las vistas son la capa de presentación. Los controladores son capas que contienen servicios, que pueden contener objetos de su dominio, que contienen su lógica de negocios, que por lo tanto contienen la lógica de back-end de su aplicación. Las vistas solo consisten en condicionales triviales y bucles simples para iterar sobre colecciones, si sus vistas contienen algo más, lo está haciendo mal. Al igual que con la estructura regular, ha separado el back-end y el front-end, que para mí es una estructura mejor que la que sugiere.
Andy
10
Así que no faltan personas para decirme que un controlador es vajilla, por lo que va en el armario de la vajilla. Las vistas son vidrios, por lo que entran en el armario de vidrio. Yo que es un controlador de vajilla, pero yo estoy proponiendo que sería bueno tener un armario de almuerzo y cena de un armario, ya que estamos hablando de cosas que sólo se acostumbra en el almuerzo o en la cena.
bbsimonbb

Respuestas:

38

Me gustaría decir que es programación de culto de carga , pero hay razones técnicas para esta estructura. Asp.Net MVC tomó una convención sobre el enfoque de configuración para casi todo. Por defecto, el motor de vista Razor busca en el Viewsdirectorio para resolver qué vista volver desde el controlador. Sin embargo, existen algunos trucos para obtener una estructura de proyecto diferente y Microsoft incluso proporciona una función MVC llamada Áreas para permitirnos crear una estructura de proyecto más sensata. También puede implementar su propio motor de vista para especificar dónde buscar vistas.

¿Por qué digo que es programación de culto de carga y que tienes razón al respecto? El tío Bob me convenció de que la estructura de directorios del proyecto no debería decirme que es una aplicación MVC. Debería decirme que es un escaparate, o un sistema de solicitud de tiempo libre, o lo que sea. La estructura y la arquitectura de alto nivel deberían decirnos qué es esto, no cómo se implementó.

En resumen, creo que tiene razón sobre esto, pero cualquier otra estructura de directorio simplemente estaría luchando contra el marco y confía en mí cuando digo que no desea tratar de hacer que el marco Asp.Net MVC haga algo que no era Está diseñado para hacer. Es una pena que no sea más configurable realmente.


Para abordar rápidamente las inquietudes arquitectónicas, sigo creyendo que los modelos de negocio (negocio, no vista) y el DAL deberían vivir en un proyecto / biblioteca separado que se llama desde su aplicación MVC.

Es solo que el controlador realmente está muy unido a la vista y es probable que se modifiquen juntos. Todos debemos recordar la diferencia entre el acoplamiento a través de la dependencia y el acoplamiento lógico. El hecho de que el código haya tenido sus dependencias desacopladas no lo hace menos lógicamente acoplado.

RubberDuck
fuente
1
Aquí está la forma integral de controlar dónde busca la afeitadora las vistas . Podría perseverar.
bbsimonbb
3
Vi al tío Bob, a x1.25 como se sugirió. Me deja pensando que si los arquitectos de TI construyeran edificios, todos viviríamos en pequeños grupos de balsas unidas, flotando en algún lago. La vida no necesariamente sería más simple.
bbsimonbb
1
Se pone un poco más complicado. Para ubicar realmente los controladores y las vistas, querrá resolver la ruta de la vista en tiempo de ejecución, para incluir el espacio de nombres del controlador. Aquí te explicamos cómo hacerlo .
bbsimonbb
1
También eche un vistazo al desarrollo de software orientado a funciones ( fosd.net ), para la contraparte académica de lo que describe el tío Bob.
ngm
1
Ley de Conway en el trabajo. Estoy seguro de que funciona en su empresa @Flater. El diseño estándar de MVC funciona en muchas empresas, pero todavía prefiero agrupar las cosas por semántica sobre sintaxis. Las empresas para las que trabajo se han organizado en torno a productos en lugar de roles / funciones de trabajo. Creo que esta es la raíz de mi preferencia aquí.
RubberDuck
9

Cualquiera sea la razón, esta es una mala práctica. Es muy anti-OO porque los paquetes o carpetas (como quiera llamarlos) deberían tener interdependencias débiles. Las clases (o archivos) dentro de ellos deberían tener fuertes interdependencias.

Al lanzar todas las vistas en una carpeta y todos los controladores en otra carpeta, está creando dos paquetes con un acoplamiento muy muy estrecho. Esto va en contra del principio de tener dependencias débiles entre paquetes.

Una vista y un controlador son dos mitades de un todo y deben pertenecer el uno al otro. No tendría un sorteo de armario para los calcetines del lado izquierdo, y otro sorteo para los calcetines del lado derecho.

Oliver Watkins
fuente
6

Para responder a tu '¿Por qué todos ...?' pregunta: Aquí hay algunas razones potenciales, aunque no estoy completamente seguro de qué combinación de ellas es una causa real, ya que en realidad es una pregunta subjetiva

  • Para replicar la arquitectura lógica (modelo, vista, controlador) con una carpeta coincidente y una estructura de espacio de nombres

  • Por conveniencia y conveniencia de seguir la plantilla de proyecto ASP.net MVC

  • Para agrupar por espacio de nombres, ya que la Controllers/carpeta conducirá a un .Controllersespacio de nombres

  • Podría habilitar algunos escenarios en DI / IoC donde las clases de controlador solo se consultan / escanean desde un espacio de nombres que contiene / termina con 'Controladores' (esto podría ser incorrecto)

  • Para permitir que las plantillas T4 escaneen y andamien modelos y controladores para generar vistas

Siempre puede crear y seguir su propia convención si tiene sentido para su proyecto, nadie puede / lo detendrá. Pero tenga en cuenta que si trabaja en un proyecto grande y / o un equipo grande, entonces la convención predeterminada que todos conocen podría ser una mejor opción (¡aunque no necesariamente la correcta!)

Si su convención es más fácil de seguir y no obstaculiza la productividad, ¡hágalo! y tal vez incluso escribir sobre él una publicación de blog o dos para socializarlo con la comunidad de desarrolladores y obtener comentarios

Bishoy
fuente
2

Una razón para mantener las vistas y los controladores en directorios separados es cuando tienes desarrolladores front-end y back-end trabajando en un proyecto. Puede evitar que los desarrolladores front-end accedan al código de back-end (por ejemplo, para ayudar con el cumplimiento de PCI, restringiendo quién tiene acceso a código confidencial).

Otra razón es hacer que sea más fácil tener "temas" y cambiar todas las plantillas haciendo un pequeño cambio en la ruta de visualización.

Una tercera razón es tener un patrón de directorio simple al especificar vistas en el marco MVC. Es más fácil especificar el subdirectorio y el archivo en lugar de una gran ruta larga a cada vista.

El único "acoplamiento apretado" debe ser:

  1. Variables enviadas a la vista por el controlador.
  2. Forme campos o acciones en la vista, devueltos al controlador.

Uso un controlador genérico e intento mantener los nombres de las variables en la vista genérica, de modo que muchas vistas puedan usar el mismo controlador y muchos controladores puedan usar la misma vista. Por esta razón, prefiero mantener las vistas completamente separadas. El modelo es donde puede diferenciar cada "cosa" en su aplicación: pueden ser objetos con una lista de propiedades y métodos para acceder / modificar estas propiedades.

Para un código estrechamente acoplado, un enfoque que podría funcionar para usted es mantener todos los archivos que forman parte de un paquete o "módulo" juntos en un directorio con espacio de nombres. Luego puede usar un script para copiar o "compilar" sus plantillas en bruto en el directorio principal de "vistas". Por ejemplo:


    lib/my-namespace/my-package/
        -> controllers/
        -> models/
        -> views/
            -> theme/
               -> template-name1
    app/compiled_views/theme/
        -> url/path/template-name1

Desafortunadamente, si desea cambiar la estructura de un tema existente, hay más entradas y salidas de directorios de paquetes para actualizar las vistas.

Tenga en cuenta que las vistas son solo una forma de formatear datos, ya sea json, xml, csv o html. Esto ayuda especialmente si desea que su aplicación también funcione como API. Intente desacoplar la vista de los datos, utilizando nombres de variables genéricos, para que pueda usar la misma plantilla para muchos controladores o modelos (o use incluye para minimizar la cantidad de código que necesita mantener).

Frank Forte
fuente
1

No necesariamente todos hacen esto. Por ejemplo, el framework Django de python tiene el concepto de una aplicación, donde los submódulos de su aplicación viven en sus propios directorios con sus propios modelos y vistas y plantillas (las vistas son lo que Django llama esencialmente controladores). Prefiero esa forma de hacer las cosas porque eso significa que puedo empaquetar fácilmente una "aplicación" y reutilizarla en proyectos simplemente incluyéndola en la lista de aplicaciones en la configuración de mis proyectos. También es más fácil averiguar dónde están las diferentes partes. Si miro el archivo urls.py y veo algo así url(r'^users/', include('my_site.users.urls')), sé que el módulo my_site.userscontiene todo el código que maneja a los usuarios. Sé mirar los módulos my_site.users.viewsy my_site.users.modelscuándo quiero ver cómo se crean y autentican los usuarios. Sé que todas mis rutas están definidas en my_site.users.url.

Además, si es lo suficientemente genérico, probablemente pueda usar ese módulo en otros sitios simplemente cambiando la configuración o empaquetarlo como una biblioteca y publicarlo como OSS.

Pavel Penev
fuente
1

Recuerde que es la forma recomendada por Microsoft de mantener los controladores y las vistas en una carpeta diferente, por lo que muchos seguirían la estructura recomendada,

  1. Una razón por la que los controladores pueden ser siempre no tiene una relación uno a uno con las vistas, especialmente las vistas parciales se pueden compartir entre los controladores.
  2. Otra razón podría ser que cuando su proyecto crezca, es posible que desee extraer los controladores y las pruebas unitarias a otro (s) proyecto (s), pero es bastante difícil hacer lo mismo para que las vistas más las vistas / js / css estén juntas, ya que se refieren entre sí.

Dicho esto, hay muchas publicaciones sobre cómo hacerlo a tu manera, como esta .

Pelican de bajo vuelo
fuente
"Es la forma recomendada por Microsoft" ... ¿Puede aclarar lo que quiere decir con eso? ¿Existe un artículo de MS real y autorizado sobre esto? ¿O es solo la configuración predeterminada del proyecto para una aplicación MVC? Y, si está basando esto en lo último, ¿no es posible que la configuración predeterminada del proyecto MVC sea lo que es porque es cómo lo hace "todo el mundo"?
svidgen
1
Basado en el artículo msdn.microsoft.com/en-us/library/… dice "Controladores, que es el recomendado" y así sucesivamente para las vistas, etc.
Low Flying Pelican
0

Para el registro

¿Por qué digo que es programación de culto de carga y que tienes razón al respecto? El tío Bob me convenció de que la estructura de directorios del proyecto no debería decirme que es una aplicación MVC. Debería decirme que es un escaparate, o un sistema de solicitud de tiempo libre, o lo que sea. La estructura y la arquitectura de alto nivel deberían decirnos qué es esta cosa, no cómo se implementó.

Pregunta: ¿Quién tiene acceso al código? Programadores. ¿A los usuarios finales les importa el código? No. Y, lo que hace un programador, codifica. O más específicamente, clases basadas en tipos (controladores, servicio, modelo, etc.). Por lo tanto, tiene sentido y es fácil depurar un código, si puede encontrar un código basado en el tipo de código, en lugar de en el comportamiento del código. Además, digamos un proyecto de equipo, uno está a cargo del controlador, otro del modelo, otro del dao y otro de la vista. Es fácil separar el proyecto en partes. Un buen código es un código fácil de depurar, no un código de sintaxis de azúcar. El tío Bob se equivoca de nuevo.

Intentar imitar el comportamiento del proyecto (el frente de una tienda) es culto a la carga.

magallanes
fuente
3
Cuando codifico, me importan más las características, no los tipos. Cuando veo que una característica no funciona como se esperaba, sé que algo está mal en el código relacionado con esa característica, aunque no necesariamente sé qué tipo de código es.
Deja de dañar a Mónica el
1
"Digamos que un proyecto de equipo, uno está a cargo del controlador, otro el modelo, otro el dao". Tal equipo tendrá dificultades para enviar cualquier cosa y cuando lo hagan, habrá costado mucho más en gastos generales de comunicación y errores.
RubberDuck
Según lo establecido en una cadena de comentarios bajo la respuesta aceptada, tiene un punto, pero solo en ciertos casos. Cuando una empresa se enfoca en proyectos MVC que vende a muchos clientes variados, mantener una estructura MVC tiene sentido para la reutilización. Cuando una empresa se concentra en un nicho (por ejemplo, tiendas web) y posiblemente utiliza muchas tecnologías diferentes, tiene más sentido tener una estructura orientada a la tienda web. Se trata de una aplicación práctica de la Ley de Conway . El código (y, por lo tanto, también la estructura del proyecto) debe seguir la estructura de la empresa.
Flater
@RubberDuck: puede argumentar por un costo adicional de cualquier manera. Tiene razón en que cuando diferentes personas hacen diferentes componentes técnicos, que ha aumentado la comunicación lógica empresarial. Sin embargo, si tiene diferentes personas que implementan completamente diferentes características, entonces puede haber aumentado los costos para asegurarse de que todos estén de acuerdo (cualificados + de acuerdo) con el uso del mismo enfoque técnico. De cualquier manera, necesita una sobrecarga de comunicación para asegurarse de que las personas trabajen juntas.
Flater
Sí, y las transferencias siempre cuestan más que tener un solo par de desarrolladores que implementan una función IME de extremo a extremo.
RubberDuck