我已经看到了存储库模式的各种用途。我倾向于一种我不太常见的模式,我想知道是否有充分的理由。
Class Teacher : IPerson
{
Private IRepository myRepository;
Internal Teacher(IRepostory repo){
This.myRepository = repo;
}
Public overrides void Save(){
Repo.Save(this);
}
}
示例:
IPerson p = DataAccess.GetPersonFromId(id);
p.Name = "Bill";
p.Save();
优势
缺点
业务对象不再是Plain Old C#对象。
对实体存储库的任何更改都可能需要更改“人员”界面。
我是否应该使用相同的模式与IFactory?我们是否继续注射服务?
IPerson p = DataAccess.GetPersonFromId(id);
IRepostory repo = DataAccess.GetRepositority()
p.Name = "Bill";
repo.Save(p);
优势
缺点
摘要
我倾向于模式1,但几乎每个我看到的例子都使用了模式2的版本。
主要目标是我不想在应用层中的任何地方使用TeacherRepository。我想完全依赖IRepository。但是,在模式2中看起来我不能这样做,因为Save()需要知道它与教师的交易才能正确地保存数据。
是否有任何独特的其他模式可以让我使用通用存储库?
答案 0 :(得分:0)
关于模式1 :它与保持域对象不仅不知道底层存储类型的原则相矛盾,而且还与它必须存储在某个地方的简单事实相矛盾。更多的是,通过应用模式1,您打破了Single Responsibility Principle:您将有两个原因来更改域对象:业务逻辑和存储。而且,从行为的角度来看,要保存不是Teacher
的责任,而是存储库的责任。因此,不再需要讨论利弊。
注意:并非所有框架都遵循良好的OOP设计。想想ORM在大多数情况下使用Active Record。他们正在使用“ class Teacher extends ActiveRecord ”之类的东西。或者施加“每个表一个类”等条件。那么,您怎么看?
关于模式2和你的问题:这里你试图强制执行我上面提到的:以某种方式标准化数据访问工作流,以便能够存储任何类型的域对象属性和结构。对象关系映射......你可以这样做,但你必须处理很多缺点。而且你必须认为你的业务在业务逻辑PLUS存储结构方面很重要。更不用说当你必须处理具有更高等级复杂性的查询时缺乏灵活性。最后 - 我听说 - 你甚至会发现有些任务实际上是不可能解决的。
所以,我的建议是让“普通旧”业务对象完全不知道存储,为它们定义特定的存储库,并从外部“绑定它们”(如通过服务)。
实际上,repository是在所谓的data mapper之上的数据访问抽象层。仅数据映射器 - 与底层数据库通信。在你的问题的背景下,你可以在这里找到一个很好的论证:
以下是其他一些资源:
祝你好运。