活动日志记录(审计跟踪)的设计模式是什么?

4
我有一个Winform,允许人们从数据库中编辑数据。为简化事情,假设数据库中有一个名为“客户”(Customer)的表格,其中有三个字段 - 姓名(Name)、城市(City)和国家(Country)。通过Winform,人们可以添加/编辑/删除客户。
对于每一种操作,我们需要保存以下内容:
1. 字段名称是什么(在这种情况下是Name,City和Country); 2. 修改前的字段值; 3. 修改后的字段值。
如果操作是添加或删除,则第二步和第三步将相同。
我已经使用XML序列化实现了此功能(但没有使用任何设计模式),我的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个回答

4
我会尝试创建几个类来处理与“审计日志”相关的事情。该日志收集了一堆“审计记录”。每个审计记录都是一个“编辑”或“删除”,如果适用,包含被更改的记录和对象的旧值。由于将涉及多种对象类型(例如客户、产品等),因此这些类型应该是通用的。
这让我想起:
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>

code: http://pastebin.com/PKiEefnX


谢谢您提供的代码,但我已经有了类似的代码,我想要尝试利用其中的一个设计模式(可能可行,也可能不可行)。 - 03Usr

1

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

如果我正确理解了你的描述,你所描述的是自dotnet 1.0以来正在执行的dotnet dataset,并且仍然适用于vs2010/dotnet 4.0,但不再由微软推广。

  • 您有每个对象类型(在您的示例中为Customer)的数据表
  • 您有带有字段(名称、城市、国家)的数据行
  • 有不同的行版本(原始、实际)
  • 您可以将其序列化/反序列化为xml(WriteXml、LoadXml、GetXml)

你描述中缺少的是一个行状态,可以用来指示已删除的行。


感谢您的输入,也许您是正确的,可能没有一个特定的设计模式能够满足我的需求。 - 03Usr

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接