用于管理大型操作结果的设计模式

时间:2009-06-14 01:31:33

标签: java design-patterns

我们经常拥有执行多部分操作/任务的对象。一个示例是基于文件系统的查询刷新对象列表的内部状态并从找到的文件中读取数据。这些东西也经常运行很长时间,并且往往是在后台线程中执行的(我们做了很多Swing工作,但我认为这种事情也适用于多层应用程序)。

在这种操作中,操作的一部分很可能会失败(即无法读取我们正在处理的5000个文件中的5个或6个)。在这种情况下,抛出异常是不合适的,但我们仍然希望向用户提供有关未发生的事情的反馈,等等......

我们一直在这里使用临时方法(例如记录,或让操作返回异常列表),但我决定严厉打击并真正考虑到这一点。

一个激励概念是验证(jgoodies有一个很好的实现)。这里的想法是,在验证表单或数据结构中的值时,可以构造ValidationResults对象,该对象可以包含ValidationResult对象。每个ValidationResult都有一个状态(OK,WARN,ERROR)以及描述性文本(以及必要的其他内容)。

我很想将Validation框架原样用于任务结果。

另一种选择是将任务的当前操作结果状态公开为绑定属性(可能使用GlazedLists事件列表)。

我想知道是否有其他人对此类事情有任何意见/经验,或者有哪些设计模式可能已经发展到可以处理长期运行的任务,这些任务可能会导致可能失败的子任务,或者不完全完美(即WARN状态)?

编辑:有关问题的澄清

许多人建议记录问题并告诉用户与管理员核实。为了澄清这个问题,请考虑像Eclipse这样的应用程序。如果构建过程有警告或错误,并且Eclipse只是给出了一个错误对话框,说“有问题,请检查日志”,我认为用户会不满意。

向用户显示当前警告和错误的列表是一种更具交互性的解决方案,并为用户提供了快速评估和解决问题的机制。

到目前为止,我们尝试过的两种方法是:

  1. 在流程结束时记录并抛出对话框
  2. 公开包含已发生例外情况的财产
  3. 我们正试图摆脱用户体验的选项1 b / c。

    选项2对我来说非常特别。它当然有效,但我正在努力寻找一种良好的,标准化的方法来解决这种情况。

    异常对于“阻止世界”失败的例程(例程以某种方式成功或失败)是有利的,抛出异常是处理这些情况的非常好的交叉机制。

    但是当一个例程不属于简单的通过/失败分类时,事情会变得有点模糊 - 例程本身可以部分成功。

    那么,传递一个我们报告问题的'ProblemListener'会更好吗?或者让例程返回问题列表更好吗?或者让对象公开上次运行例程的问题属性?

    有许多潜在的解决方案 - 我想知道是否有人有尝试这些的经验,并且他们找到了最佳实践(以及他们接受或拒绝给定方法的原因)?

6 个答案:

答案 0 :(得分:2)

为什么不记录错误,操作完成后让用户知道发生了错误,系统管理员应该查看事件日志?

临时用户可能无法理解任何技术错误。非临时用户应该足够精明,能够查看日志文件并解释结果。

答案 1 :(得分:0)

为什么不只是拥有一个包含错误的列表的公共属性,并返回一个布尔值,所以如果有错误,那么应用程序就知道要获取错误列表。

您也可以在订阅者捕获的每个错误上发送一个事件并显示错误,这样他们就会在错误发生时看到错误,因此,如果应用程序需要一个小时来处理,那么他们就不会必须等很长时间才能知道早期出现错误。

什么是好的是允许用户然后修复问题并将其添加回队列进行重新处理。 :)

答案 2 :(得分:0)

您要做的事情本质上是日志记录,因此我同意响应,即您应该只记录结果。

我会更进一步说,如果你使用log4j,你可以创建一个自定义appender,知道如何处理这种类型的日志事件并采取相应的行动(如果它是一个WARN什么都不做,如果它是一个ERROR警告用户等)。更重要的是,如果你以正确的方式设计东西,你可以通过log4j.properties(或log4j.xml)保持可配置的东西

答案 3 :(得分:0)

异常通常是表明某些操作在Java中失败的正确方法。我认为无论你的方法是什么,抛出异常,以防出现问题的方法。在我们公司,我们使用第三个库来批量保存对象,如果出现问题,整个操作都会失败,并且它们抛出的异常包含每个错误的详细信息和未导入的对象列表。然后我们再次尝试使用健康的物体。如果你不能这样做,因为你的操作不是事务性的,我会选择其中一个选项:

  • 包含异常列表和错误对象列表的异常失败;
  • 对象列表失败,每个对象包含:
    • 错误级别(ERROR,WARN);
    • 错误消息;
    • 错误的对象。

我不喜欢不抛出异常的方法(例如返回错误值),因为它依赖于开发人员在方法中检查返回值,这不是处理Java中错误的标准方法。我也不会采用日志记录方法,因为它会强制用户深入查看日志文件以找出问题所在。

我在这家拥有必须执行同步任务的客户端设备的公司工作过一次。每个客户端设备在“设备”表上都有一条记录,该表包含有关上次同步的信息 - 如果成功与否,如果没有,则出现问题。如果您的任务由服务执行,这是一个很好的方法,而不是作为方法调用的结果 - 或者更好地说,如果您的任务是异步的。有人要求启动任务,可能会或可能不会收到有关其完成的事件,并在以后检查其结果。

答案 4 :(得分:0)

你说“对象”的地方我读了批次(至少作为一个暗示),我同意日志记录是处理这个的合适的传统方式,但是使用批次ID,或者作为日志记录中的字段,或者如果监视进程,批处理大小和对象计数使其可行,则每批可能更可能是一个单独的日志文件。

答案 5 :(得分:0)

虽然这个问题已经很久了,但这是我的5分:

我会使用一个侦听器来处理在处理操作时可能出现的错误。这样,您可以通知用户操作仍在运行时发生错误。因此他也可以在中途取消手术。您甚至可以问他如何处理回调方法中的错误。

除此之外,您还可以返回一个布尔值来指示操作未成功执行完成。并且只有在操作无法处理时发生错误才会抛出异常。