如何使 IEditableObject.EndEdit 原子化?

问题描述 投票:0回答:2

如果我有一个实现 IEditableObject 的 Address 对象,我可能会有这样的 EndEdit 实现:

public void EndEdit()
{
    // BeginEdit would set _editInProgress and update *Editing fields;
    if (_editInProgress)
    {
        _line1 = _line1Editing;
        _line2 = _line2Editing;
        _city = _cityEditing;
        _state = _stateEditing;
        _postalCode = _postalCodeEditing;
        _editInProgress = false;
    }
}

例如,如果更新 _state 时出现异常,则所有 5 个属性都应重置。这个原子更新问题可能不仅限于 EndEdit。

.net transactions ieditableobject
2个回答
1
投票

首先,肯特想知道为什么设置字段会引发异常是正确的。
忽略这个问题;你可以只使用一个简单的:

try {
  //do stuff
}
catch (Exception ex) {
  //reset

  //rethrow exception
  throw;
}

问题在于每个字段的重置值由什么构成?

  • 最后一个值
  • 默认值
  • 某些标记值表示无效状态
  • 以上的混合

如果您需要“重置”到最后一个值,那么您可能需要某种方法来在对其执行某些操作之前轻松存储对象状态,并且能够在出现问题时轻松恢复该状态。查看 Momento 模式,了解解决该问题的巧妙方法。


0
投票

我不使用字段来存储值。相反,我使用属性可以读写的哈希表。这给了我一个非常简单的设计。

Friend Sub BeginEdit()
    m_Backup = New Dictionary(Of String, Object)(m_DataPoints, StringComparer.OrdinalIgnoreCase)
End Sub

Friend Sub CancelEdit()
    If m_Backup IsNot Nothing Then m_DataPoints = m_Backup
End Sub

Friend Sub EndEdit()
    m_Backup = Nothing
End Sub
© www.soinside.com 2019 - 2024. All rights reserved.