2

我有一个 4 层系统(数据库、持久性、业务、演示)。后 3 层都在一个 JVM 中运行。

我在业务层和表示层之间遇到了一些异常处理问题。将以下代码视为一个非常简化的示例

public void process(String label) throws ValidationException {

    if(label == null) {
        // this is a custom exception that means that one of the arguments invalid
        throw new ValidationException("The label can not be null.");
     }

    if(label.length() != 8) {
        throw new ValidationException("The label has to be 8 letters long."); 
    }

    ... process ...
}

这里的问题是商业轮胎不知道无效的论点是演示的错还是用户的错。

  • 假设标签是由用户提供的,那么这是用户的错,并且演示文稿必须显示“验证失败”消息以及验证异常的消息。
  • 另一方面,如果标签是由演示文稿为用户生成的,那么这是演示文稿的错误(可能是错误),并且演示文稿必须显示“内部错误”消息。
  • 此外,如果标签为空,这 100% 是演示文稿的错误。

当传递用户生成的和演示生成的参数的混合时,问题就出现了。在这种情况下,演示文稿无法知道是什么导致了异常。它唯一得到的就是向用户显示详细的消息(因为如果是用户的错,用户就会知道原因)。但是,向用户显示详细的错误消息是不可接受的,因为这是演示文稿的错,因为它只会使用户感到困惑。

在这种情况下我应该如何处理异常?有什么模式可以使用吗?

4

2 回答 2

4

从 OOP 哲学来看,数据知道自己的行为。

有很多方法可以解决问题。

这是一个想法:

  1. 为用户生成的和非用户生成的错误抛出不同的异常。如果它是用户生成的,则表示层会捕获它并显示消息。如果不是,则表示层会显示一般消息“内部错误”或“抱歉”或其他内容。
  2. 业务层不知道哪个是哪个。所以,数据必须知道。在您的示例中,label不能是字符串。它可以是一个类。

将所有参数包装在某个类中

class Label implements Validatable {
    String label;
    @Override
    public void validate() throws BaseValidationException {
         //Check conditions and throw the proper exceptions.
         //Label class should know which validations are user and 
         //Which are presentation and throw appropriate exceptions.
    }
}

为所有参数创建一个单独的类会很乏味。你可以有这样的东西:

class Argument<E>  {
    E realArgument;
    Validator validator;
    public Argument(E value, Validator validator) {
        //implement
    }

}
interface Validator {
    public void validate() throws BaseValidationException;
}

现在,您可以为标签 ( LabelValidator implements Validator) 之类的东西使用特殊的验证器,并为其他东西使用简单的验证器NotNullValidator。这些将在创建时关联。

在业务逻辑层,你得到

void process(Argument<String> label) {
    if (label != null ) label.getValidator().validate();
    //continue.
}

在表示层

try {
    process(....)
} catch (UserException ex) (
   showMessage(ex.getMessage());
) catch (PresentationError ex) {
  log.fatal(ex.getMessage());
  showMessage("Pre-formatted internal error message");
} catch (Exception ex) { //Unknown exception
  log.fatal(ex.getMessage());
  showMessage("Pre-formatted internal error message");
}
于 2012-07-06T08:21:32.470 回答
0

一旦您的应用程序生成的标签代码稳定并符合您的规范,它就不应该通过验证检查。必须有更多问题未涵盖的用例。

我能想到的一种可能的解决方案是:

您如何区分用户生成的标签和应用程序生成的标签?

如果您没有任何区分机制,我建议您在应用生成的标签上附加一些特殊的字符序列。

例如 :

  • !@_Java
  • !@_Python

所以这个“!@_”表示应用程序生成的标签,然后您可以设计一个解决方案来相应地处理任何与验证相关的问题。

如果标签通过验证步骤,您始终可以删除“!@_”部分。

请注意,您的所有标签生成仅来自特定的一段代码(最好是静态实用程序方法)。

于 2012-07-06T07:23:25.607 回答