我有一个4层系统(数据库,持久性,业务,演示)。后三层都在一个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 ...
}
这里的问题是商业轮胎不知道无效的参数是演示文稿还是用户的错误。
当传递用户生成的参数和表示生成的参数的混合时,问题就出现了。在这种情况下,演示文稿无法知道导致异常的原因。它唯一得到的是向用户显示详细消息(因为如果是用户的错,则用户必须知道原因)。但是,向用户显示详细的错误消息是不可接受的,而这是演示文稿的错误,因为它只会让用户感到困惑。
在这种情况下我该如何处理异常?有什么模式可以使用吗?
答案 0 :(得分:4)
从OOP哲学来看,数据知道自己的行为。
有很多方法可以解决这个问题。
这是一个想法:
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");
}
答案 1 :(得分:0)
一旦您的应用程序生成的标签代码稳定并符合您的规格,它就不应该通过验证检查。 必须有更多用例未包含在问题中。
我能想到的一个可能的解决方案是:
如何区分用户生成的标签和应用程序生成的标签?
如果您没有任何区分机制,我建议您在应用生成的标签上附加一些特殊的字符序列。
例如:
所以这个“!@_”表示应用程序生成标签,然后您可以设计一个解决方案,相应地处理任何与验证相关的问题。
如果标签通过了验证步骤,您可以随时删除“!@_”部分。
请注意,所有标签生成仅来自特定代码(最好是静态实用方法)。