是否有一种特定模式可以应用于通过多个操作收集数据?

时间:2011-07-26 08:20:40

标签: design-patterns software-design

我正试图通过跨多个类的多个操作/方法调用,以优雅的方式收集用于审计/历史记录的信息。有没有人对如何收集这些数据有任何想法/意见?

对于我的具体示例,我需要与Web服务进行交互以在两个系统之间同步数据。这涉及几个不同的操作,可能提供需要记录的有用信息。

为了下载数据,我需要;

  • 与Web服务通信以获取数据。
    • 要收集的数据;
      • 关于webservice查询的摘要信息(记录ID,类型,上次更新时间等)
      • 有关在Web服务调用期间抛出的任何异常的信息。
      • 从webservice
      • 检索数据(或异常)所用的时间(以秒为单位)
  • 通过本地验证规则验证收到的数据
    • 要收集的数据;
      • 验证错误。
      • 如果有效,则接收数据的XML表示和同一对象的本地表示。
  • 将验证的数据保存到本地数据库
    • 要收集的数据;
      • 数据库调用期间的任何异常
  • 保存审核/历史记录,详细说明上面收集的所有信息。

在向Web服务上传信息期间存储类似类型的数据,我们在Web服务/数据库通信期间收集例外,通过FaultException从Web服务收到验证错误,webservice通信所用的时间等。

对于我目前的解决方案,我目前创建了一个AuditHistory对象,其中包含占位符以存储各种信息,并将其传递给各种类方法并在每次方法调用期间填充它。最后,我只是保存此审计历史记录对象。

它有效,但感觉丑陋而笨重。

任何想法都表示赞赏。

3 个答案:

答案 0 :(得分:1)

我认为你的方法有效,但我会使用不同的方法;我将每个请求与GUID相关联,并传递该GUID。然后,您可以在日志记录中使用该GUID,最终您可以运行基于GUID将各种审计历史记录条目“拼接”在一起的内容,以了解通过系统的流程。在后端更多的工作是将各种日志/报告“拼接”在一起,但它将每个组件与彼此之间的任何依赖关系分离;只有一个字符串,每个字符串都必须用于记录。

另一个好处是,您只需在实际需要数据时根据请求的GUID处理构建审计跟踪的问题。因此,如果仅在2%的呼叫上需要完整的审计跟踪,则另外98%的消费将花费在不需要的AuditHistory对象上传递资源。这些资源可能相对较小,但是当AuditHistory对象发生变化时,所有相关的相互依赖性问题,以及所需的重建等等。

答案 1 :(得分:1)

您可以实现的一个相当快速的解决方法是为每个组件定义审核界面。例如,在c#中,您可以创建以下3个接口:

public interface IWebServiceAuditInfo 
{
int RecordId { set; }
string Type { set; }
ICollection<Exception> WebServiceErrors { set; }
Timespan TimeToComplete { set; }
}

public interface IValidationAuditInfo 
{
string ValidXML{ set; }
ICollection<Exception> ValidationErrors { set; }
Timespan TimeToComplete { set; }
}

public interface IDatabaseAuditInfo
{
ICollection<Exception> DatabaseErrors { set; }
}

现在,您可以让AuditHistory对象实现所有3个接口。但是,将来如果要立即记录每个接口的信息,您可以简单地提供每个接口的实现,然后将其存储(可能带有GUID用于交叉引用,如Paul Sonier所述)到数据库中。

我会在c#中使用接口的显式实现,因为这将强制您为每个字段设置别名,允许AuditHistory对象独立于使用它的组件进行更改。通过仅使您的业务组件依赖于包含所需字段的接口,如果您的AuditHistory对象实现发生更改,则不必重新编译它们。

答案 2 :(得分:1)

不完全是一种模式(更完整的范式转换),但对于您所描述的内容,您可能需要考虑Aspect-Oriented Programming

或者,如果您希望坚持使用OO范例,您可以尝试合并Observer,使您需要跟踪所有可观察的事物并让审计数据收集器观察它们。