12

I'm always facing a problem where I can't really think of service object encapsulating many DAO methods.

I mean that for my servlet sometimes it is sufficient to use single DAO method, for example addUser(User params).

What is better to do - to encapsulate DAO methods with service object and use only service objects ALWAYS, even if it literally means a single service method calling single dao method or mixing their use together(some methods from service objects and some from dao in servlet context) - meaning that I have autowired DAOs and Service objects inside controller ?

It mixes up the logic if I start to use both DAO and Service object in the same place?

skaffman
  • 398,947
  • 96
  • 818
  • 769
Aubergine
  • 5,862
  • 19
  • 66
  • 110

4 Answers4

7

I think this depends on the situation. If not having a DAO is going to cause mixing your business logic and your data access logic, it is probably better to have separate classes.

However, if your DAO is "dummy" and just calls an EntityManager method, you can probably use this directly in your service objects. The idea is to have classes that have single responsibilities and are easy to extend and test. You shouldn't be creating layers for the sake of it.

I probably wouldn't use DAOs directly from your controllers if you want to keep a reusable service layer. I would rather use the EntityManager (or whatever persistence strategy you are using) in the service layer if the DAO doesn't make sense.

  • What do you mean if it is dummy? I though that how it supposed to be? DAO has to be as simple and as dummy as possible? If you make complicated DAOs that it is probably that you already mixed up the business logic inside? – Aubergine Nov 25 '11 at 19:42
  • 2
    If you have a DAO that simply calls an EntityManager's method and that's it, why do you need the DAO? Why not using the EntityManager directly? I would use a DAO if for example I want to build a query using criteria API, which can take many lines and I don't want to get mixed with my business logic. – Gonzalo Garcia Lasurtegui Nov 25 '11 at 19:47
  • 2
    I am feeling I am talking about different thing, I am considering a case where: We have the DAO has some methods to access db. And we have service object single method which uses only single method from this DAO to perform its job. Is it feasible to create a single method in Service Object that only uses a single DAO's method, when we can use DAO method directly. Do you talk about the same thing? I have many 'EntityManager' methods. – Aubergine Nov 25 '11 at 19:53
  • 1
    I think we are talking about the same thing :) I still don't like the idea of calling DAOs directly from your controller (that's what I understood). I would rather use the EntityManager from the service instead of exposing DAOs to upper layers. – Gonzalo Garcia Lasurtegui Nov 25 '11 at 20:04
  • Yes, exactly! I needed to check. :-) to your question: "why do you need the DAO?" Because EntityManager uses dao methods? What is your EntityManager? (I don't use ORM framework yet and I am not so well famillar with design patterns is it from these areas?) – Aubergine Nov 25 '11 at 20:12
  • When I say EntityManager I mean JPA's EntityManager. This is not an object you create, it ships with a JPA implementation, like Hibernate. – Gonzalo Garcia Lasurtegui Nov 25 '11 at 20:21
5

I am working with a system where the "you cannot have the controllers interact with the DAOs!" design philosophy was embraced at a point and a service layer was created for every component. Most of the services are, as you describe, simply delegating to a DAO. I object to this philosophy for two reasons.

One is the good old "You aren't gonna need it". Don't implement something until you need it. Just because you foresee some reason to have an extra layer of indirection to do some extra logic, it's not sure you're going to need it. And when you end up needing it, you will probably find out that your expectations didn't really match what you believed earlier. And you get an extra cost, because now you have to unit test two classes instead of one, and it's not uncommon that you need to add methods in two places instead of one.

The second is, what the heck is a service anyway? When I model my domain, I try to think in object-oriented terms. There are users, therefore the User class makes sense. There are news items, therefore the NewsItem class makes sense. But I don't even know what a UserService is supposed to do. Contain "business logic" for users? No, that's what the User class is there for.

If you need to maintain a strict API to the "outside world", then I can see a case to have an extra layer that remains unchanged. But in all other cases, you aren't going to need it.

waxwing
  • 18,547
  • 8
  • 66
  • 82
  • 1
    I feel you are stretching YAGNI here. Going by you are logic, one should start with firing queries from servlet and not having any DAO. We should not code for maintenance because you have not encountered it now.If your project have multiple services just delegating calls to DAO, I see a serious flaw in the development. There should have been one common service and Dao which takes care of plain CRUD.I agree with your OOPS notion, but we are in noun kingdom(check http://goo.gl/EAZbX). You can say, we can do this but not without the cost of debugging and sometimes code duplication. – Adisesha Nov 25 '11 at 22:20
  • 1
    @Adi: I admit I was being a bit extreme, but the question was about when the service simply delegates to a DAO, and I felt someone had to play the devil's advocate. The reason why the servlet is not directly firing queries is because I also believe in the single responsibility principle. I think my aversion towards "Services" is that 90% of the examples I have seen, are either just delegating a single call to another object, or contain logic that had been better suited in a real domain object. Oh, and I enjoyed reading Yegge's post, even if I don't agree with it. :) – waxwing Nov 29 '11 at 20:30
3

Depends. The reasons to separate DAOs and Service layer are often:

  • the technical constraints (see AOP transactions in other answer)
  • architectural constraints (DTOs <=> @Entities transformation between Service layer and DAO)
  • historical (this is how it was being done for X years)
  • esthetical (to only have one layer accessed from the view layer)

Using Java EE 6 (JBoss AS 7), I don't have these burdens:

  • No AOP - @Stateless and @Transactional takes care of transactions.
  • No DTOs - I use @Entities from JPA up to the view layer.
  • Don't care about history.
  • And I prefer simplicity / less code over esthetics.

So I have most methods in DAO layer. For some cases, more complex operations, I create a service bean and perhaps use an extended persistence context.

My rule of thumb, whether a method should go into a Service bean:

  1. If it uses multiple DAOs (obviously)
  2. If it performs several entity manager calls
  3. If the implementation is likely to change, e.g. search done in JPQL vs. Hibernate Search vs. ElasticSearch.
Ondra Žižka
  • 43,948
  • 41
  • 217
  • 277
3

Personally, I usually encapsulate DAO calls within services.

This allows me to make all services transactional using AOP/etc. and use non-transactional DAO methods within those services.

For trivial services, this is an additional "layer", but IMO one that serves a purpose (and code generation of one sort or another can be used to generate it anyway). It's also rare I have only DAO functionality wrapped up in a service, though.

Dave Newton
  • 158,873
  • 26
  • 254
  • 302