2012-03-15 10 views
7

Digamos que para cada entidad de dominio, tengo un repositorio que proporciona una API a un mapeador de datos. Por ejemplo, si tengo una UserEntity, entonces tendría un UserRepository que habla con un UserMapper para persistir los datos del usuario en una base de datos.¿Dónde construir nuevas entidades de dominio? Controlador, repositorio o mapeador

Ahora, digamos que se envía un formulario en una página web y mi controlador sabe que necesita crear una nueva UserEntity en función de la información enviada.

lo hace:

  1. hacer nueva UserEntity() allí mismo, en el mismo lugar, y ejecutar todos los métodos setter necesarias de acuerdo con los datos del formulario enviado, a continuación, pasar el UserEntity a la cesión temporal, que pasa a el mapeador para la inserción?

    controlador crea UserEntity => Repo => Mapper => DB

  2. convertir los datos del formulario en una matriz, y pasarlo a la UserRepository que a continuación, ejecuta nuevo UserEntity() y los organismos, y lo pasa a el mapeador para la inserción?

    Controller pasa los datos de usuario => crea Repo UserEntity => Mapper => DB

  3. pasar la matriz a la UserRepository, que pasa a la matriz para el asignador de nuevo UserEntity y la inserción?

    regulador empieza datos de usuario => crea Repo pasa datos de usuario => Mapper UserEntity => DB

quién es la responsabilidad de gestionar la creación de objetos?

Respuesta

1

Esta es una pregunta difícil de responder. Mis dos centavos están en el número 1 por un par de razones. En primer lugar, se supone que tiene validación de dominio en su entidad que bien podría rechazar los datos que se pasan. Si eso sucediera en 2 o 3, entonces has ido unos pocos objetos antes del rechazo. Puede que no haya mucha memoria o tiempo de ejecución en términos de la diferencia entre 2/3 y 1, pero es una diferencia. Intento fallar rápido.

En segundo lugar, creo que el controlador al conocer los datos que se transmiten y los objetos es totalmente aceptable. Estoy de acuerdo con "modelo gordo, controlador delgado", pero decir que el controlador no puede saber sobre las entidades está haciendo que el controlador también delgado para mi gusto.

+0

Ese es un gran análisis de la situación. Tengo curiosidad por escuchar otros pensamientos, pero ciertamente creo que es aceptable crearlo en el Controlador. Sin embargo, tal vez menos flexibilidad? Por ejemplo, si agrego un nuevo campo a la tabla de Usuario en el DB, entonces debo recordar ir a cada Controlador que crea UserEntities. – johnnietheblack

+0

Es muy probable que esté editando la vista que acepta dicha nueva información (suponiendo que estamos hablando de una aplicación web tradicional), la edición del controlador no es demasiado exagerada. Lo más probable es que si se le olvidó editar el controlador, se olvidó de editar la vista. Además, una simple búsqueda global puede encontrar dónde se usa su clase. – Crashspeeder

+0

Otro buen punto, y si el controlador es la respuesta, entonces no estoy molesto ... pero aún así, hay una parte de mí que se siente "culpable" escribiendo el mismo proceso de creación de instancias en varios lugares. ¿No? De la misma manera, tengo mis vistas configuradas para que agregar campos de formulario que reflejen el cambio de la nueva tabla requiera un cambio en un solo archivo. – johnnietheblack

2

Sé que esta pregunta es antigua, pero pensé en pensarlo aquí ya que la única respuesta no se ha aceptado oficialmente y esto puede ser útil para los buscadores futuros. Para responder directamente a su pregunta, diría que ninguno de los anteriores. Prefiero tener un servicio adicional, un "administrador" si lo desea, para intermediar la interacción entre el controlador y los objetos repo/mapper. Cada modelo tiene un administrador dedicado para manejar su creación, actualizaciones y eliminación.

Controladores de

considero que el controlador ya que el pegamento de la aplicación. Podemos separar todas las preocupaciones que queramos en tantas piezas como sea posible, pero en algún lugar a lo largo de la línea, algo tiene que entender tanto el lado de la vista como el lado del modelo, y ese objeto es el controlador. Dicho esto, creo que los controladores deben ser delgados, por lo que el único trabajo real del controlador es asignar una solicitud a una respuesta. Cualquier tipo de procesamiento intermedio debe iniciarse en otro lugar.

En una aplicación CRUD, es bastante fácil salirse con la suya instanciando objetos nuevos y persistiéndolos en el controlador, incluso se hace más de una vez, ya que son solo unas pocas líneas para pegar. ¿Qué pasa si la creación de objetos no fue trivial? Estoy manteniendo una aplicación con muchas relaciones complejas y una creación enviada por el usuario a menudo implica la creación de muchos objetos simultáneamente. Esto no es factible de mantener en un entorno solo de controlador y modelo.

Capas de servicio extra

Para manejar esto, he creado 2 capas de servicios adicionales: FormHandler y Gerente. Cada vez que se envía un formulario, los contenidos del formulario se envían a la capa del manejador de formularios. Los manejadores de formularios son responsables de comprender los datos del formulario que entran y de normalizarlo. Los manejadores de formularios pueden pasar los datos a los objetos de administrador apropiados para su procesamiento. Los objetos de administrador procesan los datos y actualizan la capa de dominio. Ellos son responsables de crear modelos, cambiar modelos y persistir en el back-end.

De esta manera, los controladores tienen conocimiento de Solicitud, Respuesta, Formulario (posiblemente, si su marco es compatible con la creación de formularios del lado del servidor), y FormHandler. Los manejadores de formularios conocen el formulario (o los datos del formulario) y el administrador. El administrador tiene conocimiento de Repository, Mapper y Model. Observe, ahora, que los gerentes son el único punto de interacción con los modelos y el asignador, y no tienen conocimiento de los datos del formulario o la solicitud o respuesta. Por otro lado, los controladores y manejadores de formularios no necesitan saber acerca de la persistencia o los datos de la capa de dominio.

Conclusión

Con este diseño:

Controller -> FormHandler -> ModelManager -> Mapper

que he encontrado todas mis clases son ahora unidad comprobable (incluso los controladores en algún grado) debido a la separación de las preocupaciones que son muy bien dividir, y el único punto de interacción es una gran ayuda para evitar la lógica duplicada.

Notas

La cesión temporal en mi mente es sólo para la consulta de la base de datos - pidiendo que si tiene algo, no crear cosas nuevas.

Mi experiencia en este caso es el uso de Symfony 2 y Doctrina 2.

tu caso es distinto; p.ej. es posible que encuentre que la capa de formulario no es necesaria, pero la he encontrado muy útil para la transformación de datos desde formularios/vistas de datos en algo que los modelos de dominio entienden.

Cuestiones relacionadas