2011-11-25 32 views
9

Siempre me enfrento a un problema en el que realmente no puedo pensar en un objeto de servicio que encapsule muchos métodos DAO.DAO y Servicio?

Quiero decir que para mi servlet a veces es suficiente usar un único método DAO, por ejemplo addUser (parámetros de usuario).

Qué es mejor: encapsular métodos DAO con objetos de servicio y usar SIEMPRE únicamente objetos de servicio, aunque signifique literalmente un método de servicio único que invoque un método único o mezcle su uso (algunos métodos de objetos de servicio y algunos desde dao en contexto de servlet), lo que significa que he autoencargados DAO y objetos de servicio dentro del controlador.

¿Mezcla la lógica si empiezo a usar DAO y el objeto de servicio en el mismo lugar?

Respuesta

6

Creo que esto depende de la situación. Si no tener un DAO va a causar la mezcla de su lógica de negocios y su lógica de acceso a los datos, probablemente sea mejor tener clases separadas.

Sin embargo, si su DAO es "ficticio" y simplemente llama a un método EntityManager, probablemente pueda usarlo directamente en sus objetos de servicio. La idea es tener clases que tengan single responsibilities y sean fáciles de extender y probar. No deberías crear capas por el simple hecho de hacerlo.

Probablemente no use DAO directamente de sus controladores si desea mantener una capa de servicio reutilizable. Prefiero usar EntityManager (o cualquier estrategia de persistencia que esté usando) en la capa de servicio si el DAO no tiene sentido.

+0

¿Qué quiere decir si es ficticio? Pensé que cómo se suponía que fuera? DAO tiene que ser tan simple y tan tonto como sea posible? Si haces DAO complicados, ¿es probable que ya hayas confundido la lógica de negocios? – Aubergine

+2

Si tiene un DAO que simplemente llama al método de EntityManager y ya está, ¿por qué necesita el DAO? ¿Por qué no usar el EntityManager directamente? Yo usaría un DAO si, por ejemplo, quisiera crear una consulta utilizando API de criterios, que puede tomar muchas líneas y no quiero mezclarme con mi lógica comercial. –

+2

Siento que estoy hablando de cosas diferentes, estoy considerando un caso en el que: Tenemos el DAO que tiene algunos métodos para acceder a db. Y tenemos el método de objeto de servicio único que usa solo un método único de este DAO para realizar su trabajo. ¿Es factible crear un único método en el Objeto de Servicio que solo use un único método DAO, cuando podemos usar el método DAO directamente? ¿Hablas de lo mismo? Tengo muchos métodos 'EntityManager'. – Aubergine

3

Personalmente, normalmente encapsulo las llamadas DAO dentro de los servicios.

Esto me permite hacer todos los servicios transaccionales usando AOP/etc. y usar métodos DAO no transaccionales dentro de esos servicios.

Para servicios triviales, esta es una "capa" adicional, pero IMO una que sirve para un propósito (y la generación de código de un tipo u otro puede usarse para generarlo de todos modos). También es raro que tenga solo La funcionalidad DAO está envuelta en un servicio, sin embargo.

4

Estoy trabajando con un sistema en el que "no se puede hacer que los controladores interactúen con los DAO". la filosofía de diseño se adoptó en un punto y se creó una capa de servicio para cada componente. La mayoría de los servicios son, como usted describe, simplemente delegando a un DAO. Me opongo a esta filosofía por dos razones.

Uno es el bueno viejo "No vas a necesitarlo". No implemente algo hasta que lo necesite. El hecho de que prevea alguna razón para tener una capa adicional de indirección para hacer algo de lógica adicional, no es seguro de que la necesite. Y cuando termines necesitándolo, probablemente descubrirás que tus expectativas realmente no coincidían con lo que creías antes. Y obtienes un costo adicional, porque ahora tienes que probar dos clases en lugar de una, y no es raro que necesites agregar métodos en dos lugares en lugar de uno.

El segundo es, ¿qué diablos es un servicio de todos modos? Cuando modelo mi dominio, trato de pensar en términos orientados a objetos. Hay usuarios, por lo tanto, la clase de usuario tiene sentido. Hay noticias, por lo tanto, la clase NewsItem tiene sentido. Pero ni siquiera sé qué debe hacer un UserService. Contienen "lógica comercial" para los usuarios? No, para eso está la clase de Usuario.

Si necesita mantener una API estricta para el "mundo exterior", entonces puedo ver un caso para tener una capa adicional que permanece sin cambios. Pero en todos los demás casos, no lo va a necesitar.

+1

Siento que estás estirando YAGNI aquí. Pasar por usted es lógico, uno debe comenzar con las consultas de colapso de servlet y no tener ningún DAO.No deberíamos codificar el mantenimiento porque no lo ha encontrado ahora. Si su proyecto tiene múltiples servicios solo para delegar llamadas a DAO, veo un serio defecto en el desarrollo. Debería haber un servicio común y Dao que se encargara de la CRUD simple. Estoy de acuerdo con su noción de OOPS, pero estamos en el reino nominal (ver http://goo.gl/EAZbX). Puede decir que podemos hacer esto, pero no sin el costo de la depuración y, a veces, la duplicación de código. – Adi

+1

@Adi: admito que estaba siendo un poco extremo, pero la pregunta era sobre cuándo el servicio simplemente delega en un DAO, y sentí que alguien tenía que ser el abogado del diablo. La razón por la cual el servlet no está activando directamente las consultas es porque también creo en el principio de responsabilidad única. Creo que mi aversión hacia los "Servicios" es que el 90% de los ejemplos que he visto, simplemente están delegando una sola llamada a otro objeto, o contienen lógica que se ha adaptado mejor a un objeto de dominio real. Ah, y disfruté leyendo la publicación de Yegge, incluso si no estoy de acuerdo con ella. :) – waxwing

+0

tienes mi voto :) – Adi

3

Depende. Las razones para DAOs separadas y la capa de servicio son a menudo:

  • las limitaciones técnicas (ver transacciones AOP en otra respuesta)
  • limitaciones arquitectónicas (DTO < => @Entities transformación entre la capa de servicio y DAO)
  • histórica (esto es lo que se está haciendo por X años)
  • estético (que sólo tienen una capa que se accede desde la capa de vista)

Uso de Java EE 6 (JBoss AS 7), No tengo estas cargas:

  • No AOP - @Stateless and @Transactional se ocupa de las transacciones.
  • Sin DTOs - Utilizo @Entidades de JPA hasta la capa de vista.
  • No importa la historia.
  • Y prefiero simplicidad/menos código sobre estética.

Así que tengo la mayoría de los métodos en la capa DAO. Para algunos casos, operaciones más complejas, creo un bean de servicio y quizás use un extended persistence context.

Mi regla de oro, si un método debe entrar en un grano de servicio:

  1. Si se utiliza múltiples DAOs (obviamente)
  2. Si se lleva a cabo varias gestor de la entidad llama
  3. Si la aplicación es es probable que cambie, por ejemplo búsqueda realizada en JPQL vs. Hibernate Search vs. ElasticSearch.