我不明白持久性独立的意义

时间:2012-06-18 13:55:05

标签: c#

  

可能重复:
  What are the benefits of Persistence Ignorance?

经过一段时间和一些试图找出实体框架的问题后,我得出的结论是,我只是没有得到持久性无知对象的意义。

据我所知,使用持久性感知对象和持久性无知对象之间的实际区别在于,可以使用像

这样的东西。
Person p = Person.Load(id);
p.Active = false;
p.Save();

,另一个沿

行使用
using (var context = new MyContext())
{
   Person p = context.Persons.Single(x => x.ID == id);
   p.Active = false;
   context.SaveChanges();
}

在第一种情况下,我可以返回p,稍后再拨打Save()。在后者中,我可以返回p,但我需要将其放入新的MyContext()中以保存它。在第一种情况下,假设Person从实际处理数据库逻辑的某个基础对象继承Load()和Save(),如果我想更改持久性,它只涉及更改该基础对象(或者甚至只有{ {1}}多个基类可以实现访问多个商店的接口。在后者中,如果持久层发生了变化,我需要更改IPersistent的每个实例,并且要零碎地执行它会非常复杂。

我的印象是持久性 - 无知是一件好事。我只是无法理解为什么。看起来设置,使用,改变批发和改变零碎都要复杂得多,而且没有任何优势。我只是遗漏了一些重要的东西,或者我对持久性意识/无知意味着什么有缺陷的完全理解?

2 个答案:

答案 0 :(得分:5)

坚持不懈是关注分离的一部分。你应该问问自己,为什么人应该知道它应该如何加载或保存?人应该处理自己的小域名。

PI表示Person并不关心它是来自内存,SQL,平面二进制还是任何其他Persistance方法,并允许您在以后点将您的持久层替换为其他内容。您最初可能会开发应用程序以使用平面二进制文件和基本序列化程序来存储数据。稍后,您可能出于性能原因升级到SQL--并且只需在-job-处理持久性的关联层/组件的位置中进行此更改。否则,你必须通过整个代码库来改变处理持久性的小部件。

答案 1 :(得分:1)

只是想谈谈你的例子,通过编写Person.Load(id)你说 - 通过查看他的标识符加载这个对象 - 你正在创建一个刚性的工厂模式,由wich如果您知道他们的ID,您只能获取对象,以后您会发现需要根据某些搜索条件提取记录,并且您将添加更多工厂方法,而第二个解决方案已经为您提供了所需的所有自由。

第二种解决方案非常适合在运行时切换持久性逻辑,因为它与对象模型分离,您可以理论上决定在客户端代码中使用持久性引擎,而无需硬编码和触摸您的OM,如果您需要更改 MyContext 的每个实例,这是错误的,您应该编写客户端代码,让它从某种工厂类或依赖注入接收上下文。

作为一个例子,你可以有这个伪代码:

var person = onlineDbContext.Persons.Single(x=>x.Guid == myguid);

offlineDbContext.Persons.Add(person)
offlineDbContest.SaveOrUpdate();