我尝试了解Repository
模式以在我的应用中实现它。我在某种程度上坚持了它。
以下是应用程序访问数据的简化算法:
第一次应用没有数据。它需要连接到Web服务才能获取此数据。因此,与Web服务交互的所有低级逻辑都将隐藏在WebServiceRepository
类之后。从Web服务传递到应用程序的所有数据都将被缓存。
下次应用程序将请求数据时,将在从Web服务请求数据之前在缓存中搜索此数据。 Cache将自身表示为数据库和XML文件,并将通过CacheRepository
。
缓存数据可以处于三种状态:有效(可以显示给用户),无效(无法显示的旧数据)和部分有效(可以显示但必须尽快更新)。
a)如果缓存的数据有效,那么在我们得到它们之后我们就可以停止了。
b)如果列表数据无效或部分有效,我们需要访问WebServiceRepository
。如果对Web服务的访问成功结束,则所请求的数据将被缓存,然后将显示给用户(我认为这必须作为对CacheRepository
的第二次调用实现)。
c)因此,数据访问的入口点是CacheRepository
。只有在没有完全有效的缓存时才会调用Web服务。
我无法弄清楚在哪里放置验证缓存的逻辑(有效/无效/部分有效)?在哪里拨打WebServiceRepository
的电话?我认为这个逻辑不能放在Repositories
的任何一个中,因为违反了SOLID的单一责任原则(SRP)。
我应该实现某种RepositoryService
并将所有逻辑放入其中吗?或者有没有办法链接WebServiceRepository
和WebServiceRepository
?
实施该模式和方法有哪些?
另一个问题是如何从缓存中获取部分有效的数据,然后在一个方法的调用中请求Web服务?我认为使用代表和事件。还有其他方法吗?
请提出建议。链接上面列出的所有功能的正确方法是什么?
P.S。也许我描述的有点令人困惑。如果需要,我可以给出一些额外的说明。
P.P.S。在CacheRepository
下(以及WebServiceRepository
下)我指的是一组存储库 - CustomerCacheRepository
,ProductCacheRepository
等等。谢谢@hacktick的评论。
答案 0 :(得分:5)
如果您的webservice为不同的实体提供了crud方法,则为每个entityroot创建一个存储库。 如果有客户创建CustomerRepository。如果有带附件的文档作为子项创建一个DocumentRepository,它返回带有附件作为属性的文档。
存储库仅负责特定类型的实体(即客户或文档)。存储库不用于“交叉切割问题”,如缓存。 (即你的CacheRepository示例)
为每个存储库注入(即StuctureMap)一个IDataCache实例。
对Repository.GetAll()的调用将返回当前存储库的所有实体。每个实体都在缓存中注册。请注意缓存中该对象的ID。
对Repository.FindById()的调用首先检查缓存中的id。如果对象有效则返回它。
有关对象失效的通知将路由到缓存。您可以实现客户端失效或将消息从服务器推送到客户端,例如通过消息队列。
有关对象当前是否有效的状态的信息不应存储在实体对象本身中,而应存储在缓存中。