我正在编程库收集一些数据。它将能够切换其存储库以更改数据目标(数据库/文件)。我有更多的实体要存储,例如城市,街道等。我的计划是发布一个需要实现的界面,为自定义数据存储创建自定义存储库。
我已经看到,每个存储库都会处理一个实体。但在这种情况下,应该有更多的接口 - 对于每个存储库。是否可以(在存储库设计模式中)创建单个存储库,接受所有需要的实体并只发布一个接口?有了更多的接口,就有可能忘记实现一些并创建不一致的数据api。
有更好的方法来解决这个问题吗?
答案 0 :(得分:2)
每个存储库都可以返回不同的实体。但是如果你在一个界面中将所有内容组合在一起,那么其他开发人员就很难阅读和维护。在我的开发项目中,我们尝试确保每个存储库返回相关实体。希望这会有所帮助。
答案 1 :(得分:2)
我通常会选择混合,因为我有一个基础存储库并且扩展了需要自定义实现的存储库。
即:
public class BaseRepo<T> : IRepo<T> where T: TEntity
{
// common functionality for all repos
// such as find, add, remove etc.
}
但是,大多数情况下,您需要的不仅仅是CRUD,尤其是选择。
传递表达树是一个可怕的想法,这会破坏你的可测试性和可维护性。
此外,如果你有一个单独的回购,你将无法使用依赖注入,你肯定是可行的。但非常沮丧。
您需要分离存储库的职责。遵循SOLID原则。并创建一个很好的API。
答案 2 :(得分:1)
我建议创建一个GeographicRepository
,其中包含对多个数据源的引用,并接受featureType
作为参数。
使用它的一种可能方法是(伪代码):
var rep = new GeoRepository();
var citylist = rep.getEntities(featureType='city');
// or instead:
var citylist = rep.getCities()
编辑:基于中央回购与碎片回购的建议是RepositoryFaçade
成为个人(和可单独测试的)存储库的聚合器:
var centralRepo = new GeoRepository();
centralRepo.connectRepository(new GoogleCityRepo());
centralRepo.connectRepository(new YahooVillagesRepo());
centralRepo.connectRepository(new USGSDatabaseRepo('C:\usgs_usa_counties.db'));
当然,创建/声明“连接”的方式会有所不同:构造函数中的硬编码,取决于服务可用性,显式(如上所示),等等。此外,这将允许通过编写仅调用单个仓库的线束外观进行单独测试。
希望这有帮助!
答案 3 :(得分:1)
简答:是的,您可以将单个存储库用于所有操作。
长答案:当我第一次开始使用存储库时,我认为唯一的方法是为每个实体使用存储库然后我找到了这篇优秀文章"Query Objects with the Repository Pattern",其中作者讨论了是否要每个聚合根使用一个存储库,或者为每个实体使用一个存储库,或者只为整个事物使用一个存储库。他总结了一个非常诱人的意见,即使用查询对象模式的组合来查询数据源,使用单个存储库,我真的很喜欢最终结果,你可能会这样做。