2011-11-25 5 views
9

Je suis toujours confronté à un problème où je ne peux pas vraiment penser à l'objet de service encapsulant de nombreuses méthodes DAO.DAO et service?

Je veux dire que pour mon servlet, il suffit parfois d'utiliser une seule méthode DAO, par exemple addUser (User params). Quoi de mieux à faire - encapsuler des méthodes DAO avec un objet service et utiliser TOUJOURS uniquement des objets service, même si cela signifie littéralement une seule méthode de service appelant une seule méthode dao ou mélangeant leur utilisation ensemble (certaines méthodes d'objets de service et à partir de dao dans le contexte de servlet) - ce qui signifie que j'ai automatisé les objets DAO et Service à l'intérieur du contrôleur?

Il mélange la logique si je commence à utiliser à la fois DAO et l'objet Service au même endroit?

Répondre

6

Je pense que cela dépend de la situation. Si ne pas avoir un DAO va mélanger votre logique métier et votre logique d'accès aux données, il est probablement préférable d'avoir des classes séparées. Toutefois, si votre DAO est "factice" et appelle simplement une méthode EntityManager, vous pouvez probablement l'utiliser directement dans vos objets de service. L'idée est d'avoir des classes qui ont single responsibilities et sont faciles à étendre et à tester. Vous ne devriez pas créer de couches pour le plaisir.

Je n'utiliserais probablement pas les DAO directement à partir de vos contrôleurs si vous souhaitez conserver une couche de service réutilisable. Je préférerais utiliser EntityManager (ou toute stratégie de persistance que vous utilisez) dans la couche de service si le DAO n'a pas de sens.

+0

Que voulez-vous dire s'il s'agit d'un mannequin? Je pensais que c'était comme ça? DAO doit être aussi simple et aussi fictif que possible? Si vous faites des DAO compliqués, c'est probablement que vous avez déjà mélangé la logique métier à l'intérieur? – Aubergine

+2

Si vous avez un DAO qui appelle simplement la méthode d'EntityManager et c'est tout, pourquoi avez-vous besoin du DAO? Pourquoi ne pas utiliser EntityManager directement? J'utiliserais un DAO si par exemple je veux construire une requête en utilisant l'API de critères, qui peut prendre beaucoup de lignes et je ne veux pas me mêler à ma logique métier. –

+2

Je sens que je parle de choses différentes, je considère un cas où: Nous avons le DAO a quelques méthodes pour accéder à DB. Et nous avons une méthode unique d'objet de service qui utilise seulement la méthode simple de ce DAO pour accomplir son travail. Est-il faisable de créer une seule méthode dans l'objet de service qui utilise seulement la méthode d'un seul DAO, quand nous pouvons employer directement la méthode de DAO. Parlez-vous de la même chose? J'ai beaucoup de méthodes 'EntityManager'. – Aubergine

3

Personnellement, je encapsule habituellement les appels DAO dans les services.

Cela me permet de rendre tous les services transactionnels en utilisant AOP/etc. et utiliser des méthodes DAO non transactionnelles dans ces services.

Pour les services triviaux, il s'agit d'une "couche" supplémentaire, mais celle de l'IMO qui sert à un but (et la génération de code d'une sorte ou d'une autre peut être utilisée pour le générer de toute façon). C'est aussi rare que j'ai seule fonctionnalité DAO enveloppé dans un service, cependant.

4

Je travaille avec un système où le "vous ne pouvez pas avoir les contrôleurs interagissent avec les DAO!" La philosophie de conception a été adoptée à un moment donné et une couche de service a été créée pour chaque composant. Comme vous le décrivez, la plupart des services sont simplement délégués à un DAO. Je m'oppose à cette philosophie pour deux raisons.

On est le bon vieux "Vous n'en aurez pas besoin". N'implémentez pas quelque chose tant que vous n'en avez pas besoin. Juste parce que vous prévoyez une raison d'avoir une couche supplémentaire d'indirection pour faire une logique supplémentaire, ce n'est pas sûr que vous en aurez besoin. Et quand vous finissez par en avoir besoin, vous découvrirez probablement que vos attentes ne correspondaient pas vraiment à ce que vous croyiez plus tôt. Et vous obtenez un coût supplémentaire, parce que maintenant vous devez tester deux classes au lieu d'une, et il n'est pas rare que vous ayez besoin d'ajouter des méthodes à deux endroits au lieu d'un.

La seconde est, qu'est-ce que c'est que le service? Quand je modélise mon domaine, j'essaie de penser en termes orientés objet. Il y a des utilisateurs, donc la classe User a du sens. Il y a des nouvelles, donc la classe NewsItem a du sens. Mais je ne sais même pas ce qu'un UserService est censé faire. Contenir la "logique métier" pour les utilisateurs? Non, c'est la raison pour laquelle la classe User est là.

Si vous avez besoin de maintenir une API stricte pour le "monde extérieur", alors je peux voir un cas pour avoir une couche supplémentaire qui reste inchangée. Mais dans tous les autres cas, vous n'en aurez pas besoin.

+1

Je sens que vous étirez YAGNI ici. En passant, vous êtes logique, on devrait commencer par tirer des requêtes depuis le servlet et ne pas avoir de DAO.Nous ne devrions pas coder pour la maintenance parce que vous ne l'avez pas rencontré maintenant. Si votre projet a plusieurs services qui ne font que déléguer des appels à DAO, je vois une faille sérieuse dans le développement. Il devrait y avoir un service commun et Dao qui prend soin de CRUD simple. Je suis d'accord avec votre notion de OOPS, mais nous sommes dans le royaume de nom (vérifier http://goo.gl/EAZbX). Vous pouvez dire, nous pouvons le faire mais pas sans le coût du débogage et parfois la duplication du code. – Adi

+1

@Adi: J'avoue que j'étais un peu extrême, mais la question portait sur le moment où le service délègue simplement à un DAO, et j'ai senti que quelqu'un devait jouer le rôle du défenseur du diable. La raison pour laquelle le servlet ne tire pas directement des requêtes est que je crois aussi au principe de la responsabilité unique. Je pense que mon aversion pour les "Services" est que 90% des exemples que j'ai vus, soit ne font que déléguer un seul appel à un autre objet, soit contiennent une logique mieux adaptée à un objet de domaine réel. Oh, et j'ai aimé lire le post de Yegge, même si je ne suis pas d'accord avec ça. :) – waxwing

+0

vous avez mon vote :) – Adi

3

Dépend. Les raisons de OTI séparées et la couche de service sont souvent:

  • les contraintes techniques (voir les transactions AOP dans d'autres réponses)
  • contraintes architecturales (DTO < => @Entities transformation entre la couche de service et DAO)
  • historique (ce qui est la façon dont il a été fait pour X années)
  • esthétique (seulement avoir une couche accessible à partir de la couche de vue)

Utilisation de Java EE 6 (JBoss AS 7), Je n'ai pas ces fardeaux:

  • Non AOP - @Stateless et @Transactional s'occupe des transactions.
  • Aucun DTO - J'utilise @Entities de JPA jusqu'à la couche de vue.
  • Ne vous souciez pas de l'histoire.
  • Et je préfère la simplicité/moins de code sur l'esthétique. J'ai donc la plupart des méthodes dans la couche DAO.

Dans certains cas, des opérations plus complexes, je crée un bean service et peut-être utiliser un extended persistence context.

Ma règle générale, si une méthode doit aller dans un grain de service:

  1. Si elle utilise plusieurs OTI (évidemment)
  2. Si elle effectue plusieurs appels gestionnaire d'entités
  3. Si la mise en œuvre est susceptible de changer, par exemple recherche effectuée dans JPQL vs Hibernate Search vs ElasticSearch.