Responsibilities and use of Service and DAO Layers
I am currently developing a web application using Struts2 with Spring plugin and hibernate and while I was looking at online examples I saw the use of Service and DAO layers now it came to me what are the real use of Service and data access object layers? If The Service layer is just calling the methods of DAO layers to perform CRUD operations. wouldn't be sensible to just call the DAO layers methods directly?
Let's say this example of Dao and Service Layer
PeopleService
@Transactional
public class PeopleService {
private PeopleDao pDao;
public PeopleDao getPDao() { return pDao; }
public void setPDao(PeopleDao peopleDao) { this.pDao = peopleDao; }
public void createPerson(String name){
pDao.createPerson(name);
}
public List<Person> getPeople(){
return pDao.getPeople();
}
}
PeopleDao
public class PeopleDao {
private SessionFactory sessionFactory;
public void setSessionFactory(SessionFactory sessionFactory) {
this.sessionFactory = sessionFactory;
}
public Session sess() {
return sessionFactory.getCurrentSession();
}
public Person getPersonById(long id) {
return (Person) sess().load(Person.class, id);
}
public void deletePersonById(long id) {
sess().delete(getPersonById(id));
}
public void createPerson(String name) {
Person p = new Person();
p.setName(name);
sess().save(p);
}
@SuppressWarnings("unchecked")
public List<Person> getPeople() {
return sess().createQuery("from Person").list();
}
}
My question is what is the real use of Service layers if they are only being injected by their representative DAO and then calling its method?
It is a good idea to have those two layers when your business logic is more complex than your data logic. The service layer implements the business logic. In most cases, this layer has to perform more operations than just calling a method from a DAO object. And if you're thinking of making your application bigger, this is probably the best solution.
Imagine you want to include a City entity and create a relationship between People and City. Here is an example:
@Transactional
public class PeopleService {
....
private PeopleDAO pDAO;
private CityDAO cDAO;
...
public void createPerson(String name, String city)
throws PeopleServiceException {
Person p = new Person();
p.setName(name);
City c = cDAO.getCityByName(city);
if (c == null) throw new ServiceException(city + " doesn't exist!");
if (c.isFull()) throw new ServiceException(city + " is full!");
c.addPeople(p);
sess().save(p);
sess().save(c);
}
...
}
In this example, you can implement more complex validations, like checking the consistency of the data. And PersonDAO has not been modified.
Another example:
DAO and Service layers with Spring
Definition of Service layer pattern
If your application will grow with new and changing requirements you are very well served with having distinct layers for those TWO DISTINCT ASPECTS (persistence->DAO, business use case -> services) of your software.
One aspect is your persistence model with its relations, validations, transactions and many access patterns.
The services are driven by the business use cases which have a very different granularity. In the beginning you may have very simple services which don't do much more than calling DAOs to hand over data they received from, let's say, a web page. But this is likely to change over time and services will grow into small networks of collaborating objects that do a lot more to serve the business use case. If you don't use DAOs then
- your services will contain code that deals with querying objects, transaction handling, validation, all of which has nothing to do with real business requirements
- service code will look messy and it will be difficult to find out what parts of the code are actually business related
- if you then change the persistence model you might end up changing many services
Also you can not easily unit test your persistence model but write tests only on the service layer. Do not forget that decoupling and encapsulation are important techniques to minimize the impact of change.
When done right, having a DAO layer will not introduce much implementation overhead so there is not much extra cost in having it. It will soon pay off and you will be very glad to have this dedicated layer.
Check out this article: http://codeblock.engio.net/?p=180. It also comes with a full implementation hosted on github