服务和DAO层的责任和使用

我目前正在使用带有Spring插件和hibernate的Struts2开发一个Web应用程序,当我查看在线示例时,我看到了Service和DAO层的使用,现在我看到了Service和数据访问对象层的真正用途是什么? 如果服务层只是调用DAO层的方法来执行CRUD操作。 直接调用DAO图层方法是不明智的?

让我们说这个Dao和服务层的例子

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 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 getPeople() { return sess().createQuery("from Person").list(); } } 

我的问题是,如果服务层只是由他们的代表DAO注入然后调用它的方法,它的真正用途是什么?

当您的业务逻辑比数据逻辑更复杂时,最好使用这两个层。 服务层实现业务逻辑。 在大多数情况下,除了从DAO对象调用方法之外,该层必须执行更多操作。 如果你想让你的应用程序更大,这可能是最好的解决方案。

想象一下,您想要包含一个城市实体并在人与城之间建立关系。 这是一个例子:

 @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); } ... } 

在此示例中,您可以实现更复杂的validation,例如检查数据的一致性。 PersonDAO尚未修改。

另一个例子:

使用Spring的DAO和Service层

服务层模式的定义

如果您的应用程序将随着新的和不断变化的需求而增长,那么您可以很好地为您的软件的两个独特方面(持久性 – > DAO,业务用例 – >服务)提供不同的层。

一个方面是您的持久性模型及其关系,validation,事务和许多访问模式。

这些服务由具有非常不同粒度的业务用例驱动。 在开始时,您可能拥有非常简单的服务,这些服务除了调用DAO来交付他们从网页上接收的数据之外没有什么用处。 但这可能会随着时间的推移而发生变化,服务将发展成为协作对象的小型网络,这些协作对象可以为业务用例提供更多服务。 如果你不使用DAO那么

  • 您的服务将包含处理查询对象,事务处理,validation的代码,所有这些都与实际业务需求无关
  • 服务代码看起来很混乱,很难找出代码的哪些部分实际上与业务相关
  • 如果您随后更改持久性模型,则最终可能会更改许多服务

此外,您无法轻松地对持久性模型进行unit testing,而只是在服务层上编写测试。 不要忘记,去耦和封装是最小化变化影响的重要技术。

如果做得好,拥有DAO层将不会引入太多的实现开销,因此没有太多额外的成本。 它很快就会得到回报,你会非常高兴拥有这个专用层。

看看这篇文章: http : //codeblock.engio.net/?p = 180 。 它还附带了一个在github上托管的完整实现