【发布时间】:2011-10-04 15:50:44
【问题描述】:
随着在我的项目中引入 Hibernate,我的代码开始变得真正耦合,并且在许多地方都出现了样板(应该反过来,对吧?)
我被一个特定的例子弄糊涂了。我一直认为 DAO 对象本质上是非常通用的(主要封装了基本的 CRUD 操作以及后端存储实现)
不幸的是,随着我的实体类开始变得越来越复杂,我开始将越来越多的逻辑卸载到 DAO 对象中。我有一个特别的例子:
我的实体类User应该有一个叫做friends的关系,它本质上是一个用户的集合。但是,我必须将我的类映射到 UserFriendship 对象的集合,每个对象都包含对朋友对象的引用,还包含其他特定的友谊数据(友谊发生的日期)
现在,很容易在实体类中引入自定义 getter,它将获取 UserFriendship 对象的集合并将其转换为 User 对象的集合。但是,如果我只需要我的朋友集合的一个子集,比如在分页中,该怎么办。我不能在实体对象中真正做到这一点,因为它无权访问会话,对吗?这也适用于我需要对关系进行参数化查询时。有权访问会话的是 UserDAO。所以我最终得到了这个
用户DAO => 普通的 CRUD 方法 => getFriends(整数偏移量,整数限制); => 一堆类似的 getter 和 setter,负责管理 User 实例中的关系。
这太疯狂了。但我真的无能为力。我不知道是否可以在实体类中声明计算属性,也可以对其进行参数化。
从技术上讲,我也可以将 DAO 包装在实体中,并将帮助器 getter 和 setter 放回实体类中,它们应该在哪里,但我不确定这是否也是一个好习惯。
我知道DAO应该只能被控制器对象访问,它应该提供一个或多或少完整的实体对象或一组实体对象。
我很困惑。我的所有 DAO 对象或多或少现在都耦合了应该在实体对象或控制器中的逻辑。
如果我的问题有点令人困惑,我很抱歉。表述起来有点困难。
【问题讨论】:
-
有效问题 - 但是为了获得更好的答案,我会将您的问题总结为最后的简单 1-2 句要点。
-
要添加到您的列表中的一件事是服务。我们的 DAO 执行简单的数据库操作,并且不包含太多(如果有的话)逻辑。我们的实体只是数据持有者。控制器中包含业务逻辑,但通常它们只是构建模型并选择视图。如果我们需要对数据库中的实体进行逻辑处理(过滤、缓存等),那么我们就有了一个服务层。
-
您会将以下方法 getFriends(Criterion criteria) 和 getPhotos(Criterion criteria) 放在哪里?我会说他们应该留在 User 实体实例中。否则,将它们放入 DAO 和服务中不是破坏 OOP 模型吗?
-
我的意思是,我发现调用 PhotoDAO 并查询属于给定用户的照片,而不是获取用户实例,然后简单地调用 getPhotos(...)