>直接在域对象内从相关数据映射器调用必要的find()方法
>将关系逻辑写入本机数据映射器(这是示例在PoEAA中倾向于执行的操作),然后调用域对象中的本机数据映射器函数.
在我看来,为了保留“胖模型,瘦小控制器”的咒语,域对象必须意识到数据映射器(无论是自己的,还是可以访问系统中的其他映射器) .另外,由于选项2在多个数据映射器之间创建表访问逻辑,而是将其限制在单个数据映射器中,所以选项2不必要地使数据访问层复杂化.
解决方法
存储库旨在表现为特定域对象(通常是聚合根)的内存中集合:
interface EmployeeRepository { List<Employee> retrieveBy(Criteria someCriteria); void store(Employee someEmployee); int countOf(Criteria someCriteria); // convenience methods Employee retrieveById(String id); Employee retrieveBySSN(String ssn); }
这个代码的客户端不知道这些集合是否在内存中,就像在单元测试中一样,或者在某些情况下与ORM映射器通话,或者在其他情况下调用存储过程,或者为某些域对象维护缓存.
这还没有回答你的问题.事实上,您可能有域对象具有委托给正确的存储库的save()和load()方法.我不认为这是正确的方法,因为持久性几乎不是业务领域的一部分,它给你的域对象多一个改变的原因.
查看this related question更多的漫游.
回答一下这个答案的意见:
A valid criticism. However,I’m still
confused then on how to get a single
domain object or a collection of
related domain objects when within the
context of an existing domain object.
– gabriel1836
假设员工有很多技能.我看到没有任何错误的员工仓库调用技能仓库,如下所示:
// assume EmployeeRepository talks to a DB via sprocs public Employee retrieveById(String id) { ResultSet employeeResultSet = this.database.callSproc("PROC_GetEmployeeById",new Object[] { id }); List<Skill> skills = new SkillRepository().retrieveBy(new EqualsCriteria("EmployeeId",id)); Employee reconstructed = new EmployeeFactory().createNew(). fromResultSet(employeeResultSet). withSkills(skills). build(); return reconstructed; }
另一条路线不是调用技能仓库,而是让Employee Repository调用存储过程来加载技能结果集,然后委托给技能工厂来获取技能列表.
Can’t I make a call to the Repository
and whether it issues a call to the
data mapper or loads the object
in-memory is its concern,isn’t it? –
gabriel1836
非常正确.我通常以这种方式在单元测试中嘲笑整个数据层.