Where to put such business logic? Service vs DAO?

Rey Libutan picture Rey Libutan · Jun 16, 2013 · Viewed 7.9k times · Source

Given:

  1. Spring MVC - Hibernate.
  2. Controller -> Service -> DAO
  3. Now I have a method which retrieves something from the DB and EVERYTIME it does this, has to do another method say "processList" (something like just changing some values in the list depending on some screen parameters).

Question:

  1. What layer do I put this "processList"? (Controller, Service or DAO? and why)

I really need some j2ee clarifications now, I know that MVC is the same across languages but I just need to be sure :) If I am doing this in .net I would have undoubtedly put this in service.

Answer

Pavel Horal picture Pavel Horal · Jun 16, 2013

This really depends on what processList is doing exactly. There is no golden rule. Some rules I try to follow are:

  1. Never make calls between main objects on the same layer.
    • ManagementServiceImpl should never call NotificationServiceImpl.
  2. Don't make circular dependencies between objects.
    • This is very similar to the one above.
  3. If you find yourself repeating some logic across multiple main object, try to restructure the code and extract it in specialized logical classes (this will improve unit-testing as well).
    • E.g. UserUpdateHandler or NotificationDispatcher (these are still owned by the service layer -> noone else is allowed to call them)...
  4. Put the code where it logically belongs.
    • Don't get distracted by the fact, that some class needs to do something. It might not be the right place for the code.
  5. Never write fully generalised code before you need to.
    • This has its term as premature generalisation, which is a bad practice similar to premature optimisation. Saving few lines of code now can lead to pulling your hair out in the future.
  6. Always write code which is able to become generalised.
    • This is not a contradiction with the previous. This says - always write with generalisation in mind, however don't bother with writing if it is not needed. Think ahead, but not necessarily act ahead.
  7. Leave business logic to service layer, data persistence logic to data layer and user interaction logic to presentation layer.
    • Don't try to parse user input in service layer. This does not belong there similarly as counting final price in e-shop application does not belong to presentation layer.

Some examples for processList:

  • Example I - fetching additional relations via Hibernate#initialize
    • This is something which is really in between the service and DAO layer. On older projects we had specialized FetchHandler class (owned by service layer). In newer projects we leave this completely to DAOs.
  • Example II - go through list and add business validation messages to the result
    • service layer, no doubt
  • Example III - go through the list and prepare UI messages based on the validation errors
    • presentation layer

Side note:

  • MVC is a different thing from three-layered architecture.
  • M model spans across all three layers. Presentation layer includes both V views and C controllers.