实现“脏”标志function的不同方法

几乎每个程序员都曾经这样做过:如果variables的值发生变化,就设置一些标志。 总是有很多属性,你想跟踪如果有什么改变

  1. 在任何财产
  2. 在一个特定的属性
  3. 或者在一些属性集合中

我感兴趣的是不同的方式来实现上述情况的“脏旗”function ,除了每个属性更改标准对象宽脏标志更新。 必须有一些东西比在每个制作者中设置“肮脏=真实”更好:它看起来很丑,而且是一个单调乏味的工作。

对于我的DAO,我保留了从数据库中检索的原始值的副本。 当我发送更新,我只是比较原来的价值观与当前。 它在处理上花费了一些钱,但比每个房产都有脏标志要好得多。

编辑进一步certificate没有脏标志:如果属性返回到原来的值,没有办法反映,脏标志继续肮脏,因为原来的价值已经失去。

我曾经有一个基本的实体类,提供脏/删除逻辑。

在编写实体 – 子类时,可以执行如下操作:

public string Name { get { return name; } set { setValue("Name", value); } } 

这工作正常,但有'丑陋的string'疾病…

今天,您可以使用Lambdaexpression式排除string:

 set {setValue(x => x.Name, value);} 

或者,我认为这是最好的解决scheme,你可以使用AOP :

https://www.postsharp.net/

这样,您可以按属性定义操作。 您创build一个属性并指定当用户更改关联的属性时,该实体变脏。

此外,您可以保留您的class级(基本实体)中的属性列表,以记住已更改的属性,并从您的AOP代码中访问该列表。

我创build了一个名为DirtyValue<T>的类,它有一个原始值和一个当前值。 在第一次使用时,它将设置原始值和当前值。 连续呼叫只设置当前值。

你可以通过比较这两个variables来判断它是否已经改变了,它是一个名为IsDirty()的只读bool属性。 使用这种技术,您也可以访问原始值。

如果你正在设置一个“肮脏的”国旗意识到你正在保持状态。 在某个时候,你需要根据这个状态采取行动,否则你不需要保持国旗。 那么问题就变成了:是否有另一种方式来触发所需的行动? 发送某种消息? 谁消耗“脏”的状态,并采取行动,并有一个更清洁的通知接口?

在一些使用数据写入器任务和独立阅读器任务的情况下,我已经给每个任务一个updateCountvariables。 生产者在写入时增加其计数。 每当读者醒来,发现它的计数小于生产者的数量时,它就用当前值进行更新。 计数器溢出需要一些特殊的处理,但这很容易实现。

我已经在模拟中成功地使用了这种技术 – 制作者是物理循环,读者是3d显示器。

我会把改变()在每个setter,即调用一个私人的方法,而不是只改变一个标志。 然后该方法可以设置一个标志或做任何需要的处理,例如它也可以通知任何观察者。

对于明确的dirty=true方法来说,一个有趣的替代方法,尽pipe对于大多数情况来说可能是过度的,而且经常不适用,将会使用guard页面。 将内存页面设置为只读(例如,在Windows上使用VirtualProtect() ),并在程序尝试写入页面时捕获信号/exception。 logging页面已被修改,然后将页面的保护标志更改为可写,并恢复执行。

这是操作系统通常使用的技术,用于确定是否需要将页面从RAM中清除之前将其写入交换文件。

您可能希望查看重写gethashcode并等于您的域对象的方法,并通过对象键将哈希表中的原始哈希码存储在哈希表中。 然后创build一个处理对象,在散列表中find它的关键字并比较散列值。

  • 如果散列相同,则不变。 (不要发送到存储库或数据库)
  • 如果散列不同,对象有变化。 (更新)
  • 如果没有find密钥,对象是新的。 (插)
  • 不知道如何确定是否需要删除对象,而不是根据请求删除进程而不使用哈希码跟踪。

我还没有尝试过,散列表可能不是跟踪对象键/散列值的最佳方式。 它将通过仅跟踪哈希代码和密钥来保存内存。 我不是100%肯定,但我认为一些orm可能会在他们的数据上下文/跟踪对象中使用这个方法。