Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Oop 一个存储库用于多个实体?_Oop_Design Patterns - Fatal编程技术网

Oop 一个存储库用于多个实体?

Oop 一个存储库用于多个实体?,oop,design-patterns,Oop,Design Patterns,我正在编程库收集一些数据。它将能够切换其存储库以更改数据目的地(数据库/文件)。我有更多的实体要存储,如城市、街道等。我的计划是发布一个接口,该接口需要实现,以创建自定义数据存储库 我已经看到,每个存储库负责一个实体。但在这种情况下,每个存储库应该有更多的接口。是否可以(在存储库设计模式中)创建一个存储库来接受所有需要的实体并只发布一个接口?有了更多的接口,就有可能忘记实现一些接口并创建不一致的数据api 有更好的方法解决这个问题吗?我建议创建一个geographicalposition,其中包

我正在编程库收集一些数据。它将能够切换其存储库以更改数据目的地(数据库/文件)。我有更多的实体要存储,如城市、街道等。我的计划是发布一个接口,该接口需要实现,以创建自定义数据存储库

我已经看到,每个存储库负责一个实体。但在这种情况下,每个存储库应该有更多的接口。是否可以(在存储库设计模式中)创建一个存储库来接受所有需要的实体并只发布一个接口?有了更多的接口,就有可能忘记实现一些接口并创建不一致的数据api


有更好的方法解决这个问题吗?

我建议创建一个
geographicalposition
,其中包含对多个数据源的引用,并接受
featureType
作为参数

一种可能的使用方法是(伪代码):

编辑:基于中央回购与分散回购的建议是将
RepositoryFaçade
作为单个(和可单独测试的)存储库的聚合器:

var centralRepo = new GeoRepository();
centralRepo.connectRepository(new GoogleCityRepo());
centralRepo.connectRepository(new YahooVillagesRepo());
centralRepo.connectRepository(new USGSDatabaseRepo('C:\usgs_usa_counties.db'));
当然,创建/声明“连接”的方式会有所不同:在构造函数中进行硬编码,具体取决于服务可用性、显式(如上所示)等等。此外,这将允许通过编写一个仅称为单一回购协议的治理结构来进行单独测试


希望这有帮助

每个存储库可以返回不同的实体。但是,如果您将所有内容都集中在一个接口中,其他开发人员将很难阅读和维护。在我的开发项目中,我们试图确保每个存储库返回相关的实体。希望这对您有所帮助。

简短回答:是的,您可以对所有操作使用单个存储库


详细回答:当我第一次开始使用存储库时,我认为唯一的方法是为每个实体使用一个存储库,然后我发现了这篇优秀的文章,作者讨论了是为每个聚合根使用一个存储库,还是为每个实体使用一个存储库,还是只为整个事情使用一个存储库。他最后提出了一个非常诱人的观点,即使用单一存储库来处理所有问题,并结合查询对象模式来查询数据源。我非常喜欢最终结果,您可能也会喜欢。

我通常选择混合存储库,因为我有一个基本存储库和扩展存储库,需要定制实现

即:

公共类BaseRepo:IRepo其中T:tenty
{
//所有回购协议的通用功能
//例如查找、添加、删除等。
}
然而,大多数情况下,您需要的不仅仅是CRUD,尤其是对于selects

传递表达式树是一个可怕的想法,它会破坏您的可测试性和可维护性

此外,如果您有一个单一的回购协议,那么您将无法使用依赖注入,这当然是可行的。但是非常气馁


您需要分离存储库的责任。遵循坚实的原则。并创建一个好的API

如果您想了解有关地理特征存储库的一些想法,您可以从这里获得一些灵感(它涉及WEB服务,但不一定必须是基于WEB、基于http或基于xml的):对于我的需要,这将是正确的方法。我的存储库将保持简单-我只需要保存大约10种实体。但是所有的工作都应该在一个事务中完成,所以这样我就不用执行这种工作单元了。因为其他答案也很有用,所以投票表决吧。谢谢你们的建议。我完全不同意作者的观点,也不同意你们和其他人的观点。你也可以找到许多不同意的作者。首先,你的可测试性会很差,因为你需要为一个给定的回购协议提供更多的通用功能。此外,传递表达式3和IQueryable也不是一个好主意。遵循坚实的原则@DarthVader我不想在这里的评论中开始讨论,但我想指出,我仍然在使用每个实体的接口。这样一来,我想说的是,作者实现其想法的方式是非常可测试的,不涉及到处传递表达式树,而且我觉得这仍然比有人声称他是针对每个实体进行存储库更好,因为他实际上是从一个公共基类派生存储库,包括所有违反所有规则的各种操作分类或原则。我不是在开始讨论,而是从继承违反各种原则开始。利斯科夫潜艇怎么样。原则?@DarthVader这正变成一场讨论。我说的不是继承,而是基类,它包含各种各样的操作,它们假装它对所有返回IQueryable和接受表达式树的存储库都是通用的。最后一件事,上帝知道我喜欢多态性,liskov子原则是我最喜欢的原则之一。我想指出一些可能重要的方面:1)设计模式旨在用作一般原则,以适应每个特定需求;2) 使用一个实际上是不同(类型)数据源的“mashup”的存储库是Façade模式和Adapter模式(据我所知)的一个很好的例子,除了作为存储库模式之外。3) 即使是最著名的奥霍(脑海中浮现的是马丁·福勒)也不那么自信地认为一种方法是“错误的”,而另一种方法是“正确的”。每一种明智的做法都有好处也有缺点。依我拙见
var centralRepo = new GeoRepository();
centralRepo.connectRepository(new GoogleCityRepo());
centralRepo.connectRepository(new YahooVillagesRepo());
centralRepo.connectRepository(new USGSDatabaseRepo('C:\usgs_usa_counties.db'));
public class BaseRepo<T> : IRepo<T> where T: TEntity
{
  // common functionality for all repos
  // such as find, add, remove etc.
}