我正在编程库收集一些数据。它将能够切换其存储库以更改数据目的地(数据库/文件)。我有更多实体要存储,例如城市、街道等。我的计划是发布一个需要实现的接口,以便为自定义数据存储创建自定义存储库。
我已经看到,每个存储库都处理一个实体。但是在这种情况下,应该有更多的接口——每个存储库。是否可以(在存储库设计模式中)创建一个接受所有需要的实体并仅发布一个接口的存储库?有了更多接口,就有可能忘记实现一些并创建不一致的数据 api。
有没有更好的方法来解决这个问题?
我正在编程库收集一些数据。它将能够切换其存储库以更改数据目的地(数据库/文件)。我有更多实体要存储,例如城市、街道等。我的计划是发布一个需要实现的接口,以便为自定义数据存储创建自定义存储库。
我已经看到,每个存储库都处理一个实体。但是在这种情况下,应该有更多的接口——每个存储库。是否可以(在存储库设计模式中)创建一个接受所有需要的实体并仅发布一个接口的存储库?有了更多接口,就有可能忘记实现一些并创建不一致的数据 api。
有没有更好的方法来解决这个问题?
每个存储库可以返回不同的实体。但是,如果您将所有内容组合在一个界面中,其他开发人员将很难阅读和维护。在我的开发项目中,我们尝试确保每个存储库都返回相关实体。希望这可以帮助。
我通常会选择混合,因为我有一个基础存储库和需要自定义实现的扩展存储库。
IE:
public class BaseRepo<T> : IRepo<T> where T: TEntity
{
// common functionality for all repos
// such as find, add, remove etc.
}
但是,大多数时候您需要的不仅仅是 CRUD,尤其是对于选择。
传递表达式树是一个糟糕的主意,它会扼杀你的可测试性和可维护性。
此外,如果您只有一个 repo,您将无法使用依赖注入,这当然是可行的。但非常气馁。
您需要分离存储库的职责。遵循 SOLID 原则。并创建一个好的 API。
我建议创建一个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'));
当然,创建/声明“连接”的方式会有所不同:在构造函数中硬编码,取决于服务可用性,显式(如上所示)等等。此外,这将允许通过编写仅调用单个 repo 的线束外观来进行单独测试。
希望这可以帮助!
简短回答:是的,您可以将单个存储库用于所有操作。
长答案:当我第一次开始使用存储库时,我认为唯一的方法是为每个实体使用一个存储库,然后我发现了这篇出色的文章“使用存储库模式查询对象”,其中作者讨论了是否对每个聚合根使用单个存储库或每个实体的存储库,或整个事物的单个存储库。他总结了一个非常诱人的观点,即使用单个存储库来处理所有内容,并结合查询对象模式来查询数据源,我真的很喜欢最终结果,你可能会喜欢。