验证-抛出异常还是返回False?

时间:2020-01-09 10:35:58  来源:igfitidea点击:

验证输入数据时,如果输入无效,则不必总是引发异常。如何处理无效数据或者合理地声明状态通常取决于以下条件:

Can the code detecting the error, interact sensibly with the
user, to correct the error?

如果错误是由用户的输入引起的,并且该用户能够更正输入并重试,则通常更喜欢进行交互而不是抛出异常。另外,我们可能希望在将输入中所有可能的错误显示给用户之前,先进行检测。这样,用户可以在下一次重试之前更正所有错误,而无需重复进行更正,重试,更正,重试等重复操作。例如,在servlet中,我们可以这样:

public void service(HttpServletRequest request,
                  HttpServletResponse response){
  boolean isStreetvalid  = validateStreet (request);
  boolean isZipCodeValid = validateZipCode(request);
  boolean isPhoneValid   = validatePhone  (request);

  if(isStreeValid && isZipCodeValid && isPhoneValid){
      //perform action
  } else {
      //redirect back to HTML form and show the three errors.
  }

}

请注意,没有任何一种验证方法会引发异常。而是它们返回true或者false。即使输入数据无效,也无需引发异常。

相反,在DAO类中,我们很可能无法与用户进行交互以更正错误。 DAO对象甚至可能不知道是否从Web服务,Servlet或者其他地方调用了它。它无法知道输入是否来自其他系统,文件或者用户。它无法知道如何通过与用户的交互来解决错误,甚至无法解决该错误。

在这种情况下,DAO对象发出错误信号的标准方法是引发异常。可以使用其他机制,例如返回码等,但这不会改变DAO无法自行处理错误的事实。在调用DAO之前,应已验证输入数据。这是它的外观:

public void insertAddress(Address address){

  validate(address);

  //insert address
}

public void validate(Address address) {

   if(isInvalidCity(address.getCity()){
       throw new InvalidArgumentException(
        "City " + address.getCity() + " is not valid");
   }

   // more if-statements like the one above,
   // validating each field in the address object.
}

在此示例中,一旦发现验证错误,validate()方法将引发异常。 insertAddress方法无法与用户交互以更正错误。因此,抛出异常来发出错误信号是适当的。或者,可以在引发异常之前检测到所有错误。