在构造函数中尝试/捕获 – 推荐的做法?

我一直很好奇的东西

public class FileDataValidator { private String[] lineData; public FileDataValidator(String[] lineData){ this.lineData = lineData; removeLeadingAndTrailingQuotes(); try { validateName(); validateAge(); validateTown(); } catch(InvalidFormatException e) { e.printStackTrace(); } } //validation methods below all throwing InvalidFormatException 

不建议在我的构造函数中包含try / catch块吗? 我知道我可以让Constructor将Exception抛回给调用者。 你们在调用像我在构造函数中所做的那样的方法时,你们更喜欢什么? 在调用类中,您更喜欢创建FileDataValidator的实例并在该实例上调用那里的方法吗? 只是有兴趣听一些反馈!

在您显示的代码中,validation问题不会与创建此对象实例的代码进行通信。 这可能不是一件好事。

变化1:

如果在方法/构造函数中捕获exception,请确保将某些内容传递回调用方。 你可以把一个字段isValid设置为true,如果一切正常的话。 这看起来像这样:

 private boolean isValid = false; public FileDataValidator(String[] lineData){ this.lineData = lineData; removeLeadingAndTrailingQuotes(); try { validateName(); validateAge(); validateTown(); isValid = true; } catch(InvalidFormatException e) { isValid = false; } } public boolean isValid() { return isValid; } 

变化2:

或者您可以将exception或其他exception传播给调用者。 我已将其显示为未经检查的exception,但根据您的exception处理宗教做任何工作:

 public FileDataValidator(String[] lineData){ this.lineData = lineData; removeLeadingAndTrailingQuotes(); try { validateName(); validateAge(); validateTown(); } catch(InvalidFormatException e) { throw new com.myco.myapp.errors.InvalidDataException(e.getMessage()); } } 

变化3:

我想提到的第三种方法有这样的代码。 在调用代码中,您必须调用构造函数,然后调用build()函数,该函数将工作与否。

 String[] lineData = readLineData(); FileDataValidator onePerson = new FileDataValidator(); try { onePerson.build(lineData); } catch (InvalidDataException e) { // What to do it its bad? } 

这是类代码:

 public FileDataValidator() { // maybe you need some code in here, maybe not } public void build(String[] lineData){ this.lineData = lineData; removeLeadingAndTrailingQuotes(); try { validateName(); validateAge(); validateTown(); } catch(InvalidFormatException e) { throw new com.myco.myapp.errors.InvalidDataException(e.getMessage()); } } 

当然, build()函数可以使用你调用的isValid()方法来查看它是否正确但exception对于构建函数来说似乎是正确的方法。

变化4:

我想提到的第四种方法是我最喜欢的方法。 它有这样的代码。 在调用代码中,您必须调用构造函数,然后调用build()函数,该函数将工作与否。

这种方式遵循JaxB和JaxRS的工作方式,这与您的方式类似。

  1. 外部数据源 – 您有一个文件,它们有XML或JSON格式的传入消息。
  2. 用于构建对象的代码 – 您拥有代码,他们的代码库根据各种JSR中的规范工作。
  3. validation与对象的构建无关。

调用代码:

 String[] lineData = readLineData(); Person onePerson = new Person(); FileDataUtilities util = new FileDataUtilities(); try { util.build(onePerson, lineData); util.validate(onePerson); } catch (InvalidDataException e) { // What to do it its bad? } 

以下是数据所在的类代码:

 public class Person { private Name name; private Age age; private Town town; ... lots more stuff here ... } 

以及用于构建和validation的实用程序代码:

 public FileDataValidator() { // maybe you need some code in here, maybe not } public void build(Person person, String[] lineData){ this.lineData = lineData; removeLeadingAndTrailingQuotes(); setNameFromData(person); setAgeFromData(person); setTownFromData(person); } public boolean validate(Person person) { try { validateName(person); validateAge(person); validateTown(person); return true; } catch(InvalidFormatException e) { throw new com.myco.myapp.errors.InvalidDataException(e.getMessage()); } } 

我倾向于通过知道如何处理它们的代码来处理exception。 在这种情况下,我会假设创建FileDataValidator的代码位知道如果文件数据无效将会发生什么,并且exception应该在那里处理(我主张传播给调用者)。

在讨论最佳实践时 – 类名FileDataValidator闻起来像我。 如果您正在创建的对象存储文件数据,那么我将其称为FileData – 可能使用validate方法? 如果您只想validation文件数据,那么静态方法就足够了。

您应该考虑静态工厂模式。 使所有参数构造函数成为私有的。 提供静态FileDataValidator(args …)方法。 这接受并validation所有参数。 如果一切正常,它可以调用私有构造函数并返回新创建的对象。 如果有任何失败,抛出一个Exception来通知调用者它提供了错误的值。

我还必须提到这一点:catch(例外e){printSomeThing(e); }

是否可以用例外来做最致命的反模式。 是的,您可以在命令行上读取一些错误值,然后呢? 调用者(提供错误值的人)没有得到错误值的通知,程序执行将继续。