恐怕你稍微误解了存储库模式的意图。
存储库的行为类似于特定域对象的内存集合,通常是聚合根:
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() 方法。我认为这不是正确的方法,因为持久性几乎从来都不是业务领域的一部分,它为您的领域对象提供了不止一个改变的理由。
查看此相关问题以了解更多内容。
针对对此答案的一些评论:
一个有效的批评。但是,我仍然对如何在现有域对象的上下文中获取单个域对象或相关域对象的集合感到困惑。– 加布里埃尔1836
假设一个员工有很多技能。我认为员工存储库调用技能存储库没有任何问题,如下所示:
// 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;
}
另一种方法是不调用技能存储库,而是让员工存储库调用(在此示例中)存储过程以加载技能的结果集,然后委托给技能工厂以获取技能列表。
我不能调用存储库,它是否会调用数据映射器或将对象加载到内存中,不是吗?– 加布里埃尔1836
非常正确。我通常以这种方式在我的单元测试中模拟出整个数据层。