Pregunta

Estoy pensando si realmente necesito una capa de servicio.

Estoy usando la primavera + Hibernate para una aplicación swing de escritorio y en este momento tengo GUI / pivotar capa-> servicio de capa-> DAO capa. Yo uso la primavera sólo para el apoyo @Transactional y la COI de inyección

Las mejores prácticas decir que tengo para escribir un servicio a utilizar mis daos, y poner todas las operaciones de gestión en el servicio.

Pero me estoy dando cuenta de que muy a menudo, capa de servicios únicos métodos Dao replicados, así por ejemplo:

// a DAO example
@Repository
public class CustomerHibernateDAO extends BaseHibernateDAO implements CustomerDAO {

 public List<Customer> findAllCustomerILikeName(String name){
  return getSession()
   .createCriteria(Customer.class)
   .add(Restriction.ilike("name", name))
   .list();
 }
}

// Customer service to use this dao...
@Service
@Transactional
public class CustomerService {

 @Autowired
 CustomerDAO customerDAO;

 // Why i can't call DAO instead the service?
 public List<Customer> getAllCustomersByName(String name){
      return customerDAO.findAllCustomerILikeName(name);
 }

}

Este es un uso típico de la mina capa de servicio ... Hibernate es db-agnóstico, primavera son Tecnology agnóstica: así, realmente lo necesito

¿Qué hay de una clase de servicio única para gestionar todos DAO ?? Creo que esto puede ser una buena solución de compromiso, o bien, es una mala práctica?

Sé que puse en @Transactional DAO es una mala manera, pero en este momento no tengo a los servicios de escritura sólo para poner @Transactional en él ...

Editar

Más información Sobre mi aplicación.

Mi aplicación es un software de gestión y gestionar el registro de usuarios, productos, orden y otras cosas así. En la práctica, contiene una gran cantidad de lectura entidad-> Editar-> Guardar entidad o Create-> Editar-> operaciones de guardar, y, gracias a hibernar, estas operaciones son gestionados por uno DAO mayor parte del tiempo, lástima pues de hibernación con @manyto. .. recolección y cascade.save_update permisos para guardar dos o más entidades en la misma persisten operación.

Así, por ejemplo, en mis artículos JFrame donde puedo insertar, modificar o crear un elemento (un producto a vender) hay:

public ItemFrame(){
 // the constructor
 itemService=springAppContext.getBeans(ItemService.class);
}

public boolean validateForm(){
 // test if the gui is correctly filled by user
}

public boolean save(){
 // create an Item entity taking value from swing gui(JTextField etc)
 Item item=new Item();
 item.setName(nameTextField.getText());
 item.setEtc...
 // ItemService ' save method is a wrap around itemDao.save(item)...
 itemService.save(item);
}

private void saveItemActionPerformed(ActionEvent evt){
 // When i press SAVE button
 if(validateForm()){
  save();
 }
}

Esto es lo que tengo en la mayoría de los casos, por lo que creo que se cayó en la anémica-dominio-anti patrón ...

Gracias.

¿Fue útil?

Solución

Si sus duplicados capa de servicio Dao, usted no está utilizando la capa de servicio en absoluto. Hice el mismo error en algunas de mis aplicaciones, me preguntaba "por qué el servicio de capa miradas tan feo, y está DAO duplicationg" ...

La capa de servicio debe ser de interfaz para su Appliacation, esto hicieres media, que algunos métodos no son los mismos en DAO y en el servicio, pero la parte principal es significativamente diferente. No puedo decir esto sin ver el resto del código, sino por su pregunta (que es casi lo mismo que eran mis preguntas hace unos meses), me parece, que está utilizando modelo de dominio anémico antipatrón . En el modelo de dominio anémico, el modelo contiene sólo los campos y los captadores, métodos reales (de comportamiento), que viola los principios fundamentales orientados a objetos (objeto de datos == + comportamiento) ... su comportamiento es probablemente en algo que se parece a la escritura de transacción en el servicio capa, pero debe estar en su modelo (capa de dominio).

La salida de este es el uso de modelo de dominio rico (frijoles inyectaron a través de modelo @Configurable). Usted puede decir, que esto viola el patrón de capas y usted será probablemente correcta. Pero estoy convencido de que debemos pensar en nuestra aplicación (dominio + DAO + servicio) como un solo componente (ver Alistair Cockburn hexagonales Arquitectura / puertos y adaptadores ).

Su cliente de aplicaciones swing / web, entonces será un cliente a su componente principal, a continuación, puede cambiar sin ningún tipo de limitaciones (pd todo lo que los datos modiefies es en el núcleo).

Sin embargo, hay una limitación / desventaja de este enfoque. Si va a utilizar algún tipo de seguridad (seguridad de primavera) o registros activos a través de hibernación, lo que debe comunicarse con todos los clientes a través de DTO (no las entidades en sí), ya que al entidad de contacto, se puede llamar al servicio, que será activo en sí mismo a través de transaccional y puede modificar la base de datos (bypass su seguridad).

Espero, que he adivinado su arquitectura, si no, lo siento por la invención de la rueda aquí, este artículo puede ayudar a alguien que no sabe esto (como lo era hace pocos meses).

Editar

a tu edición: Incluso en la aplicación CRUD sencillo, algún tipo de acciones debe estar en la capa de servicios - por ejemplo, la validación (no la validación "se trata de un número", pero algunos de validación específica de negocios). Este shouldn estar en su punto de vista, porque si lo cambia, tendrá que copiar y pegar de nuevo. Cuando nos fijamos en el código, usted debe preguntar a un qeusting "si decido a escribir cliente ligero (vista en el navegador web)", ¿hay algún código, que voy a tener que copiar? Si la respuesta es SÍ, que se debe crear un método de servicio para esta llamada posiblemente remoto.

La otra cosa que usted debe / puede hacer en la capa de servicio es autorization (está el usuario en este papel PERMITIDO eliminar esta entrada). Lo que tendrá que tener una capa de servicio para casi todas las entidades, porque simple usuario debe ser capaz de editar (eliminar) sus entradas, pero probablemente no debería eliminar otros usuarios. Pero usuario en función de administrador puede hacer esto.

Ejemplo de código (parte de la interfaz de servicio artículo en mi aplicación (seguridad de primavera)):

@Secured("ROLE_EDITOR")
public void save(ArticleDTO selectedArticle, ArticleDetailsDTO selectedArticleDetails);

En todo el mundo el servicio comentario puede salvar sus comentarios a los artículos ....

Y una última nota: probablemente debería considerar, si necesidad capa de servicio en absoluto. Cuando su escrito de una manera agradable, su aplicación va a ganar muchas cualidades en su flexibilidad, capacidad de reutilización y facilidad de mantenimiento. Pero es muy difícil y requiere mucho tiempo para escribirlo. Si no quieres hacer esto todo este material (seguridad, modelo de dominio rico, llamando desde más interfaces (cambio de vista de la implementación)), se puede vivir sin él: -)

Otros consejos

En algún momento, la aplicación va a querer algo de lógica de negocios. Además, es posible que desee validar la entrada para asegurarse de que no hay algo malo o mora que se solicita. Esta lógica pertenece en su capa de servicios.

Por otra parte, puede ser posible para que su DAO bastante genérico, por lo que sólo tiene uno o dos métodos que no cambian mucho. Esto reduce el riesgo de hacer algo muy malo a sus clases DAO cada vez que desee agregar / cambiar la funcionalidad de la aplicación.

La DAO es para acceder a los datos. El servicio es de lógica de negocio. Mantenerlos separados y usted será más feliz en el largo plazo.

Con el tiempo, tendrá que coordinar el comportamiento entre varios de DAO. También puede introducir un poco de complejidad a sus reglas de negocio (por ejemplo: no hacer la actualización [esto], si [que] está en un estado en particular). Aquí es donde la capa de servicio viene muy bien.

Dicho esto, no es "técnicamente" equivocado nada con la eliminación de la capa de servicio completo. Sólo será un poco más dolorosa cuando finalmente decide que lo necesita.

En lugar de hacer cumplir

ui -> service -> DAO

para cada operación, lo que permite considerar tanto

ui -> DAO
ui -> service -> DAO

estando el último utilizado para operaciones más complejas

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top