Modelo gordo / controlador delgado vs. Capa de servicio

He estado desarrollando aplicaciones empresariales durante muchos años usando .Net. Mis aplicaciones generalmente tienen un modelo de dominio que contiene entidades que mapean tablas SQL DB. Uso un patrón Repositorio, inyección de Dependencia y una capa de servicio.

Recientemente comenzamos a trabajar en proyectos de MVC 3 y tuvimos un debate sobre dónde poner qué lógica. Me topé con la delgada architecture de Controller / FAT Model y me preguntaba cómo encajaría la capa de servicio en

Opción 1 – Modelo de conversaciones a servicios

El controlador es delgado, llama a los métodos en los modelos. Los modelos “saben” cómo cargarse desde el DB y hablar con repositorys o servicios. Por ejemplo, customerModel tiene un método Load (id) y carga el cliente y algunos objetos secundarios como GetContracts ().

Opción 2: el controlador habla con los servicios

El controlador le pide a los Servicios que recuperen objetos del modelo. La lógica de cargar / almacenar etc. está en la capa de servicio. El modelo es un modelo de entidad pura con solo datos.

¿Por qué la opción 1 sería una mejor opción, especialmente cuando hablamos de aplicaciones empresariales? Mi experiencia me dice que separe las preocupaciones, mantenga los modelos y controladores lo más delgados posible y tenga servicios especializados que hagan la lógica de negocios (imb.

Gracias por todos los consejos y referencias a buenos recursos.

Todo esto depende de la intención y los requisitos de su aplicación.

Dicho esto, esta es mi sugerencia para aplicaciones web de “escala media” (no un restaurante local, y no Twitter / Facebook).

  1. Modelado de dominio Lean

    Seque los objetos de estilo POCO, preferiblemente ignorantes de la architecture MVC de su aplicación web, para permanecer lo más unidos posible de su implementación particular. Tal vez incluso la biblioteca de clases pueda volver a utilizarse para una aplicación externa, por ejemplo una API REST a través de un servicio web de WCF )

    “Modelo” en MVC significa con mayor precisión el modelo que el Controlador conoce y, por lo tanto, el modelo destinado a la Vista .

    En aplicaciones más pequeñas (a menudo Tutorial), los modelos de entidad de su “Capa de Modelo de Aplicación / Dominio” suelen ser los mismos objetos instanciados que el controlador envía a una Vista.

    En aplicaciones más grandes, los desarrolladores a menudo emplean los principios de la architecture MVVM y comienzan a usar objetos separados del Modelo de Vista. Los controladores a menudo llaman a los servicios de nivel medio que trabajan con las entidades no visibles a continuación. En este escenario, la M en MVC significa con mayor precisión el Modelo de Vista.

  2. Capa de servicio robusta

    Esto no significa lógica obesa , sino servicios de propósito único bien escritos. Si bien la encoding de su lógica comercial en servicios fuera del modelo es un poco más “de procedimiento” que pura “OOP”, ayuda mucho con el acoplamiento flexible, las pruebas y la implementación flexible (por ejemplo, la implementación de n niveles).

    En mi práctica personal, codigo los servicios tanto en la capa de datos, que considero mi modelado de comportamiento de los objetos POCO (mecánica de persistencia, validación de bajo nivel, etc.), y los servicios de nivel superior (función de flujo de trabajo / negocios) más cerca de la mecánica MVC.

  3. Controladores Lean

    Me aseguro de que mi controlador sea simplemente el entrenador , ya que no es el juego (servicios) o el jugador (modelo de entidad o modelo de vista), sino que simplemente decide quién juega qué posición y qué jugada hacer. Mis controladores hacen dos cosas:

    1. Servicios de llamada que interactúan con la entidad / dominio Modelos

    2. Prepare un modelo de vista para la vista apropiada.

    Incluso las acciones de controlador autenticadas / autorizadas se realizan a través de servicios / atributos inyectados.


EDIT 1:

Tenga en cuenta que esto no significa que su Entidad / Modelo de Dominio sea o deba ser anémico. ORMs, repositorys y fábricas, validación o mecánica estatal son bienvenidos. Solo significa que para las aplicaciones de escala moderada, el Modelo en MVC representa el modelo destinado para el controlador, para entregar a su Vista .

Esperemos que este punto calme a los apóstoles de Fowler que creen que el modelo de datos anémicos es un antipatrón . Al mismo tiempo, refleja un ángulo de procedimiento un poco más que OOP donde es más puro incluir el comportamiento en las clases modeladas.

No existe una “verdad definitiva”, pero al usar este patrón, le resultará fácil construir, probar y desplegar sus aplicaciones, al mismo tiempo que se conservan muchas posibilidades de reutilización y escalabilidad.


EDICION 2:

Dicho esto, incluso para aplicaciones de tamaño moderado, sobre la architecture (que una palabra se compone nerds?) Un sistema es demasiado común. Por ejemplo, envolver un ORM con un patrón de repository y luego escribir servicios para usar el repository … todo esto es bueno para la separación de preocupaciones y demás, pero si su proyecto no requiere (y no es muy probable que pronto lo requiera) ) tales cosas, no lo construyas. No hay nada de malo en omitir todo el repository, escribir servicios empresariales delgados (por ejemplo, clases de consulta) en un ORM, o incluso tener el controlador hablando directamente con él. Todo depende de la escala.


EDIT 3:

Quería señalar que esta explicación y consejo es para el contexto de la architecture MVC del lado del servidor como ASP.Net, no para los marcos del lado inteligente como Knockout o Backbone.

Necesitas saber un poco más sobre MVC antes de seguir adelante y discutir dónde poner todo. Bueno, si quieres seguir el patrón. De lo contrario, puede dejar de leer ahora.

El patrón está muy vagamente definido. No hay nada que diga cómo deberían verse el controlador, la vista o el modelo, ni cómo deberían estructurarse. El patrón simplemente establece que debe separar las partes y cómo deben interactuar entre sí. Así que vamos a ver un poco más sobre lo que son (mi interpretación).

MVC

Modelo El modelo puede ser cualquier cosa. Puede ser un servicio web, sus repositorys, sus clases de servicio o simplemente sus modelos de dominio. El modelo es todo lo que se usa para obtener la información que necesita. Considere el “Modelo” como una capa en lugar de un solo objeto.

Controlador El controlador es un pegamento. Toma la información del Modelo y la adapta a la vista y viceversa.

Ver La vista solo debería mostrar lo que el usuario ve.

Tenga en cuenta que no debe confundir el modelo con los modelos de vista. Microsoft realmente debería haber llamado a la carpeta “Modelo” “Modelos de Vista” ya que eso es lo que son. No usaría la información del “Modelo” directamente en las vistas. Si no lo hace, tendrá que cambiar el Modelo si la Vista se cambia y viceversa.

La respuesta

El modelo no es un modelo de vista, sino una capa. Todo en el modelo se usa para obtener la información necesaria para la vista. El controlador toma esa información y la coloca en un modelo de vista única.

Una sola acción del controlador puede usar una o varias llamadas al “Modelo” para poder reunir la información que necesita la vista.

Eso significa que su segunda opción es la más correcta cuando desea obtener una aplicación que es fácil de mantener y ampliar.

Tenga en cuenta que una capa de servicio puede no ser necesaria. Puede llamar al OR / M directamente desde los controladores. Pero si te encuentras duplicando código o consiguiendo controladores gordos, simplemente mueve la lógica a una capa de servicio. Nada más que el controlador se verá afectado por ese cambio ya que está utilizando modelos de vista adecuados.

Opción 1: podría pensar que el modelo == servicio. El modelo también es la capa de negocios.

La opción 2 es un antipatrón del Modelo de dominio anémico. http://en.wikipedia.org/wiki/Anmic_domain_model

La opción 2 es lo que se describe como la architecture Fat Stupid Ugly Controllers ( Referencia al autor de esta expresión ). Esta solución generalmente está en contra del espíritu MVC ya que rompe la separación de preocupaciones.