恐怕你已经稍微误解Repository模式的意图。
资源库是为了表现得像一个内存中收集特定的域对象,通常是一个聚合根:
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以获得更多漫游。
在回应这个答案一些意见:
有效的批评。但是,我仍然 困惑,然后在如何获得一个单一的 域对象或一个 相关域对象的集合时,在一个现有的域对象的 上下文中。 - 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;
}
另一条路线是而不是调用的技能库,有员工储备库调用,在这个例子中,存储过程加载结果集技能,然后委托技能工厂获取技能列表。
我不能让到存储库 通话以及是否发出调用 数据映射器或加载在内存中的对象 是其关注的,不是吗? - gabriel1836
没错。我通常以这种方式在单元测试中嘲笑整个数据层。
你能否提供一个例子来说明如何处理在现有的域对象中加载其他域对象?例如,如何为员工加载技能集合? – 2009-01-22 04:28:40
您希望存储库对象执行此操作...领域模型应该是坚持不懈的,但是应该有另外一个知道持久性的对象。 – Webjedi 2009-01-22 04:46:50