活动记录(审计跟踪)的设计模式

时间:2012-06-15 09:34:06

标签: c# vb.net oop design-patterns xml-serialization

我有一个winform,允许人们编辑数据库中的数据,简化事情,假设数据库中有一个Customer表,包含3个字段 - Name,City,Country。通过winform,人们可以添加/编辑/删除客户。

对于我们需要保存的每项操作:

  1. 字段名称是什么(名称,城市,本例中为国家/地区)

  2. 字段值在修改之前的含义

  3. 修改后的字段值是什么。

  4. 如果操作是添加或删除,那么2和3将是相同的。

    我已经使用XMLSerialisation(但没有使用任何设计模式)实现了这一点,我的XML输出看起来像这样。

    <?xml version="1.0" encoding="utf-8"?>
    <ActivityItem xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
      <UserID>26</UserID>
      <FormTitle>frmCustomer</FormTitle>
      <Action>Edit</Action>
      <Area>Customers</Area>
      <TrackedActivity>
        <FieldNames>
          <string>Name</string>
          <string>City</string>
          <string>Country</string>
        </FieldNames>
        <PreValues>
          <string>CompA</string>
          <string>London</string>
          <string>UK</string>
        </PreValues>
        <PostValues>
          <string>CompB</string>
          <string>Manchester</string>
          <string>UK</string>
        </PostValues>
      </TrackedActivity>
      <DateTimeStamp>2012-06-15T10:16:18</DateTimeStamp>
    </ActivityItem>
    

    该解决方案可以处理具有不同字段数的系统的不同区域(例如,当您修改产品时,同样适用)。

    我的问题是,是否有一个定义明确的设计模式来处理这种行为?

    非常感谢

2 个答案:

答案 0 :(得分:4)

我会做什么...产生几个班级。有一个“审计日志”的东西收集了一堆“审计记录”的东西。每个审核记录都是修改删除,并包含已更改的记录和对象的旧值(如果适用)。

好的,因为会涉及多种对象类型(Customer,Product,...),这对我说这些类型应该是通用的。

这让我:

public class AuditLog<T>
{
    public int UserID   { get; set; }
    public string LastSaved   { get; set;}

    [XmlArrayItem("Entry")]
    public List<AuditRecord<T>> Records;
}

public enum Flavor
{
    Edit,
    Delete
}

public class AuditRecord<T>
{
    public AuditRecord() { Stamp = DateTime.Now; }

    [XmlAttribute("action")]
    public Flavor Action  { get; set;}

    [XmlAttribute("stamp")]
    public DateTime Stamp   { get; set;}

    public T Before;
    public T After; // maybe null
}

然后是这样的课程

public class Customer
{
    public string Name   { get; set; }
    public string City   { get; set; }
    public String Country   { get; set; }
}

...你会得到这样的文件:

<AuditLogOfCustomer>
  <UserID>0</UserID>
  <LastSaved>2012 Jun 16 20:42:53</LastSaved>
  <Records>
    <Entry action="Edit" stamp="2012-06-16T20:42:52.9622344-07:00">
      <Before>
        <Name>Sheldon</Name>
        <City>Ipswich</City>
        <Country>UK</Country>
      </Before>
      <After>
        <Name>Sheldon</Name>
        <City>London</City>
        <Country>UK</Country>
      </After>
    </Entry>
    <Entry action="Delete" stamp="2012-06-16T20:42:52.9642345-07:00">
      <Before>
        <Name>Sheldon</Name>
        <City>London</City>
        <Country>UK</Country>
      </Before>
    </Entry>
  </Records>
</AuditLogOfCustomer>

代码: http://pastebin.com/PKiEefnX

答案 1 :(得分:1)

我还没有听说过一个特定的设计模式,你在这里做了什么,但我称之为离线可更新的数据库快照

如果我正确阅读了您的描述,您可以描述 dotnet dataset 自dotnet 1.0以来所做的工作,并且仍在使用vs2010 / dotnet 4.0,但不再由微软推广。

  • 您拥有每种对象类型的数据表(在您的示例中为客户)
  • 您有包含字段(名称,城市,国家/地区)的数据行
  • 有不同的行版本(原始,实际)
  • 你可以(de)将其序列化为xml(WriteXml,LoadXml,GetXml)

您的描述中缺少的是 rowstate ,可用于指示已删除的行。