1

在阅读了一些关于类层次结构应该如何的指南之后,我对分层架构非常陌生,+ spring + hibernate -

我想出了这个结构:

public interface GenericDAO {

   public <T> T getItemById(long id, Class<T> c);

   public <T> int save(T... objectsToSave);

   public <T> int saveOrUpdate(T... objectsToSave);

   public <T> int delete(T... objectsToDelete);
       .
       .
}

现在我所有的其他 daos 实现都使用这个通用 dao 作为私有字段,以便使用它的基本方法:即:

@Repository
public class UserDAOImpl implements UserDao {

      @Autowired
      private GenericDAO dao;

      @Override
      public int deleteUser(User u) {
        return dao.delete(u);

      }

      .
      .
      .
}

我的服务是这样的:

 @Service
 public class UserServiceImpl implements UserService {

     @Autowired
     private UserDao userDao;


     @Transactional(readOnly = false)
     public int deleteUser(User u) {
         return userDao.deleteUser(u);
     }
         .
         .
         .
 }

我不明白为什么我的项目中需要 UserDaoImpl 、 CarDaoImpl 、 XDaoImpl ?这似乎真的是多余的,因为所有 XDaoImpls 看起来都一样:

 @Repository
 public class UserDAOImpl implements UserDao {

      @Autowired
      private GenericDAO dao;

      @Override
      public int deleteUser(User u) {
        return dao.delete(u);

      }

      .
      .
      .
}

@Repository
public class CarDAOImpl implements CarDao {

      @Autowired
      private GenericDAO dao;

      @Override
      public int deleteCar(Car c) {
        return dao.delete(c);

      }

      .
      .
      .
}

@Repository
public class XDAOImpl implements XDao {

      @Autowired
      private GenericDAO dao;

      @Override
      public int deleteX(X c) {
        return dao.delete(c);

      }

      .
      .
      .
}

我不能创建任何 XDaoImpl 而是使用 GenericDaoImpl 并节省大量的类创建,不是吗?

如果需要像 deleteUserCar(User u) 这样的复杂操作,我可以在服务中实现逻辑:

UserService {
          public void deleteUserCar(User u) {
             Car c = u.getCar();
             CarService cs.deleteCar(c);

          }  
}

我错过了什么吗?谁能提供一个例子,只使用 GenericDaoImpl 而不是 XDaoImpl 会让我后悔吗?

谢谢

4

2 回答 2

1
  • 您的服务稍后将调用业务逻辑,而不仅仅是将方法传递给 DAO。它可以验证值(例如它是否存在以及它是否应该是唯一的),运行计算(例如int getStock() { return bought - sold; }等等。

  • 通用 DAO 很棒,尽管考虑 aabstract class而不是interface. 这样你就不需要创建多个create()s,只需扩展抽象的DAO(例如CarDAO extends AbstractDAO<Car>)。

  • 您的扩展 DAO 会将class它的句柄传递给通用抽象 DAO(如前面的示例所示)。

  • 您的扩展 DAO 稍后将实现仅适用于该特定对象的额外方法,例如:List<Car> getCarsWithColor(Color color).

  • 您的 Service -> DAO 关系并不总是一对一的。考虑这些 DAO:TruckDAO, CarDAO,VanDAO对象Truck extends Vehicle, Car extends Vehicle, Van extends Vehicle. 您是否需要三个服务,或者是否需要VehicleService覆盖它(您可能会为所有Vehicles 运行逻辑)?

  • 重新考虑接口的使用,这个问题适用C#但概念是一样的。

于 2013-05-16T07:30:28.180 回答
0

我的建议是:保持简单!请不要创建太多导致太复杂的抽象,请记住,如果您创建了太多不需要的代码,那么您将被迫保留这些代码:大量您甚至不知道的垃圾它的目的是什么,大量的代码掩盖了应用程序的真正目标。

因此,在这种特殊情况下,我建议:

  1. 忘记创建 DAO 接口:它们旨在抽象 DAO 实现,以便“轻松”从数据库(例如 MySQL 到 SQLServer)切换,但想想!:这是一件非常罕见的事情:切换系统比切换系统更常见切换数据库

  2. 把那个 GenericDao 扔进垃圾桶(世界不是关于 CRUD,去找你的利益相关者,问问他们真正需要什么)

  3. 使用简单的 DAO 层和服务层,您可以使用 Spring 实现:我想您可以在 DAO 层中使用 SimpleJDBCTemplate 并在服务层中调用该 DAO 方法

  4. 为什么要使用 Spring 呢?你有没有问过自己它的目的是什么?目前我以这种方式使用 MyBatis:我创建由 POJO 服务调用的 Mapper(类似于 DAO)。简单、有用且直接,没有 Spring,简单的旧 Java,像冠军一样工作。

于 2013-12-30T04:06:17.077 回答