Tengo una lista desplegable que muestra los valores de una tabla al usuario final. Me gustaría ordenar estos valores alfabéticamente.
Según el diseño adecuado de MVC, ¿en qué capa debo colocar mi lógica de clasificación: el modelo, la vista o el controlador?
EDITAR : En respuesta a la pregunta de LarsH, "¿Te refieres al código que determina qué orden de clasificación se desea? ¿O al código que realiza la clasificación?", Originalmente me refería al código que determina qué orden de clasificación se desea.
asp.net-mvc
model-view-controller
Ryan Kohn
fuente
fuente
Respuestas:
(Nota: esta cita y cita están tomadas de la respuesta de @ dasblinkenlight , pero no estamos de acuerdo con nuestra interpretación. Lea su publicación y decídase ).
Según la descripción de MVC ,
La lógica de clasificación (p. Ej., El comparador de clasificación / algoritmo de clasificación) pertenece al modelo ya que contiene reglas comerciales y datos de estado. Dado que la alteración de la forma en que se ordenan los datos del modelo cae directamente en la categoría "cambiar la presentación de la vista del modelo", el controlador es responsable de "hacer la clasificación" llamando al método model.changeSortedState ().
fuente
public void Sort(bool sortByDescending = false)
, si es falso, se ordena ascendiendo. O simplemente tenga dos métodos de clasificación diferentes si la lógica es muy diferente.¿Quién controla el orden de clasificación?
(De Wikipedia )
1) Orden natural dentro de los datos en sí:
El orden es parte del Modelo, por lo que debe ir allí. Una extracción sin formato de "todos los datos" devolvería los datos en el orden ordenado, y no hay interfaz para elegir el orden de clasificación.
2) El usuario debe controlar cómo ven los datos:
La Vista proporcionaría una interfaz (como flechas ascendentes / descendentes) que interactúa con el Controlador, y el Modelo comprende los datos lo suficientemente bien como para hacer la clasificación solicitada en los datos. Sin embargo, una extracción sin procesar de los datos no necesariamente tiene que ser ordenada, a diferencia de (1).
En cualquier caso,
La Vista no entiende que está ocurriendo un tipo, aparte de la capacidad de mostrar qué dirección de clasificación se ha elegido. No pongas la lógica allí.
Pequeña advertencia
La funcionalidad de clasificación podría ir puramente en la Vista, bajo una circunstancia (que se me ocurra por casualidad; puede haber más):
Una clasificación "tonta" donde todos los datos ya están en la vista y no tiene que usar ningún conocimiento de dominio para hacer la clasificación. Cadena muy simple o comparación de números, por ejemplo. Esto no es posible, por ejemplo, en los resultados de búsqueda en una página web cuando es probable que los resultados se dividan en varias páginas.
fuente
Según la descripción de MVC ,
De acuerdo con esto, la lógica de clasificación pertenece al controlador, porque la alteración de la forma en que se ordenan los datos del modelo cae directamente en la categoría "cambiar la presentación del modelo de la vista".
EDITAR: Para aclarar múltiples malentendidos expresados en los comentarios, la "lógica de clasificación" no es el código que realiza la clasificación; Es el código que define el tipo. La lógica de clasificación compara elementos individuales entre sí para establecer un orden (por ejemplo, a través de una instancia de
IComparator<T>
) o contiene una lógica que construye un objeto para ser utilizado para ordenar por un sistema externo (por ejemplo, a través de una instancia deIOrderedQueryable<T>
). Esta lógica pertenece a su controlador, ya que necesita conocimientos relacionados con el lado "comercial" de su aplicación. Es completamente suficiente para realizar el ordenamiento, pero está separado del código que realmente realizaeso. El código que se ordena puede estar en su vista, en su modelo o incluso en la capa de persistencia que respalda su modelo (por ejemplo, su base de datos SQL).fuente
IComparer<T>
. La "mecánica de calderería" restante de la clasificación, incluida la recuperación de datos del modelo, depende de la vista.{Unknown, Pass, Fail}
. Además, suponga queUnknown
siempre debe ordenar al final, independientemente del orden ascendente o descendente que haya elegido el usuario. Al colocar esta lógica en la vista, su opinión se vería demasiado acerca de la naturaleza comercial de los datos dentro delcode
campo. La vista no debería saberlo: todo lo que sabe es que el usuario realizó un gesto de "clasificación" (por ejemplo, hizo clic en un encabezado); el resto depende del controlador.Ninguna de las anteriores. La clasificación es lógica de negocios, y la lógica de negocios no pertenece a ninguno de los tres. No todas las piezas de código en su aplicación serán un modelo, vista o controlador.
Lo que generalmente hago en mis aplicaciones MVC es que tengo una capa de servicio que realiza toda la lógica de negocios. Los métodos en la capa de servicio deben tener una API limpia y simple con parámetros bien nombrados. Luego puede invocar esos métodos desde su controlador para manipular los datos en los modelos.
En ese sentido, la ordenación está "en el controlador", pero el código mismo que realiza la ordenación no debe implementarse en el controlador, solo debe invocarse desde allí.
fuente
Definitivamente no es el controlador: envía mensajes para ver y modelar, pero debe hacer el menor trabajo posible. Si el usuario puede cambiar la clasificación, el controlador maneja esa solicitud informando al modelo o la vista al respecto.
Tal vez la Vista si es una cosa pura de la Vista. Si la aplicación funciona igual de bien sin clasificar, la clasificación es solo parte de la representación y debe ir en la vista.
Si el orden es parte inherente del dominio, debe ir en el modelo.
fuente
Entonces, la elección es: ¿cree que esto es parte de la lógica de negocio del dominio o de la lógica de presentación?
Si estuviera implementando un MVC Model2 apropiado o un patrón MVC clásico, entonces diría que el pedido de datos proporcionados por la capa del modelo debe ser activado por la solicitud de la vista a la capa del modelo. Ver solicita datos ordenados, la capa del modelo lo proporciona.
Pero, dado que está utilizando la interpretación de ASP.NET MVC del patrón MVC, que es un poco diferente a su MVC estándar: la instancia de ViewModel debe solicitar información ordenada de la capa del modelo (por alguna razón, el marco de ASP.NET cree que las plantillas deberían llamarse "vistas" y vistas deberían llamarse "modelos de vista" ... es extraño).
fuente
Por lo general, lo haría en el controlador para permanecer en línea con el patrón según las otras respuestas. Ver abajo para razonamiento.
He estado reflexionando sobre esto y leyendo las respuestas y el material relacionado y hablando pragmáticamente, diría que dependería de su aplicación, por ejemplo:
¿Es una aplicación mediana / grande y / o tiene múltiples IU asociadas (es decir, una aplicación de Windows, una interfaz web y una interfaz de teléfono)?
Si se trata de un sitio web de interfaz de usuario único bien definido y está utilizando algo como EF Code First y no tiene o no tiene la intención de crear una capa de servicio y planea utilizar un método de extensión simple para obtenerlo:
Si es lo mismo que el anterior PERO no se puede implementar con un método de extensión listo para usar.
Para resumir:
Respuesta dogmática: capa de servicio
Respuesta pragmática: por lo general, el controlador
fuente
Sugeriría ordenar los datos de una tabla (los datos que son lo suficientemente pequeños como para ser útiles en una lista desplegable) deberían provenir de la base de datos ya ordenada a través de la consulta. Para mí, eso hace que el modelo sea el lugar donde se aplica la clasificación.
Si está decidido a hacer la clasificación a mano, creo que hay buenos argumentos para usar el modelo o el controlador como su lugar preferido para la lógica. La limitación sería su marco particular. Prefiero administrar los datos únicamente en el modelo. Utilizo el controlador para casar datos (modelo) y presentación (vista) como me han enseñado.
fuente
Si bien estoy de acuerdo en principio con la idea de que la clasificación es Business Logic porque al desglosarla en su origen, terminaría con algo como "Al cliente le gustaría que la página del Producto se muestre con las imágenes ordenadas por fecha", entonces queda claro que el orden de clasificación de los datos generalmente no es arbitrario, incluso si no hay clasificación, ya que sigue siendo una decisión comercial por omisión (una lista vacía sigue siendo una lista).
PERO ... Estas respuestas no parecen tener en cuenta los avances en la tecnología ORM, solo puedo hablar en relación con Entity Framework (evitemos una discusión sobre si esto es ORM verdadero, ese no es el punto) de Microsoft como eso es lo que uso, pero estoy seguro de que otros ORM ofrecen una funcionalidad similar.
Si creo una vista fuertemente tipada para una clase de producto usando MS MVC y Entity Framework y hay una relación de clave externa entre el producto y la tabla de imágenes (por ejemplo, FK_Product_Image_ProductId), entonces sería capaz de ordenar rápidamente las imágenes durante su visualización usando algo como esto en la vista:
Se mencionó una capa de Business Logic específica, que también utilizo para realizar el 80% de mi lógica de negocios, pero no voy a escribir una funcionalidad de clasificación en mi capa de Business Logic que imite algo que viene de fábrica del marco de la entidad.
No creo que haya una respuesta correcta a esta pregunta, aparte de decir eso; debe abstraer la lógica empresarial compleja siempre que sea posible, pero no a costa de reinventar la rueda.
fuente
myList.OrderBy(x => x.CreationDate)
: realmente no hay necesidad de introducir ninguna capa adicional innecesaria solo para hacer esto. Para agregar a esto, ¿qué harían si necesitaran datos paginados y ordenados? ¿Consulta toda la tabla, la ordena y luego guarda lo que necesita? Uno podría simplemente llamarmyList.OrderBy(x => x.Date).Skip((page-1)*pageSize).Take(pageSize)
y no se recuperarán datos innecesarios.Suponga que tiene un sitio web de MVC, un sitio web de WebForms y una aplicación móvil.
Si desea que la ordenación sea coherente entre estas capas de presentación, entonces diría que ordenar fuera de la capa de presentación. El servicio sería un buen candidato.
De lo contrario, almacenaría esa lógica en un modelo de vista. ¿Por qué? Porque será reutilizable y fácilmente comprobable.
fuente
De los tres que ha enumerado, diría que pertenece al controlador. Sin embargo, realmente no me gusta colocar este tipo de lógica en el controlador. Por lo general, creo una capa de servicio con la que se comunica el controlador que será responsable de comunicarse con el almacén de datos y manejar la lógica de clasificación. Sin embargo, para aplicaciones pequeñas, está bien sentarse en el controlador.
fuente
Esta es una pregunta hecha con asp.net en mente, pero como alguien mencionó a Rails, pensé que sería interesante considerar el problema en ese contexto. En Rails, es natural y bastante común realizar la clasificación junto con la recuperación como una acción del controlador, ya que el marco y la API de ActiveRecord / ActiveQuery lo prevén. Por otro lado, es posible definir algún tipo de orden de clasificación personalizado para elementos estáticos y ponerlo en el modelo que utilizará el controlador, para que el modelo pueda desempeñar un papel en la lógica de clasificación aunque no se lleve a cabo. La operación directamente. Sea lo que sea, puede ser seguro decir que poner la lógica de clasificación en la vista generalmente está mal visto.
Me divierte un poco que algunas respuestas estén absolutamente en contra de poner el tipo en el controlador o en el modelo, y las encuentro demasiado pedantes para mi gusto, pero supongo que depende de la naturaleza del marco utilizado y las convenciones habituales asociadas con eso. También estoy de acuerdo con el comentario de Bill K de que tener la separación en primer lugar es más importante.
fuente