尝试/抓住建设者 - 推荐做法? [英] Try / Catch in Constructor - Recommended Practice?

查看:123
本文介绍了尝试/抓住建设者 - 推荐做法?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直很好奇

  public class FileDataValidator {

private String [ ] lineData;

public FileDataValidator(String [] lineData){

this.lineData = lineData;
removeLeadingAndTrailingQuotes();

try
{
validateName();
validateAge();
validateTown();
}
catch(InvalidFormatException e)
{
e.printStackTrace();
}

}

//下面的验证方法抛出InvalidFormatException

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

解决方案

在你显示的代码中,验证问题不会传回给代码正在创建此对象实例。这可能不是一件好事。



变体1:



方法/构造函数中的异常,请务必将某些东西传回给调用者。您可以将一个字段 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:



或者你可以让异常或其他一些异常传播给调用者。我已经将它显示为一个非检查异常,但根据您的异常处理宗教做任何工作:

  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: / strong>



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

  String [] lineData = readLineData(); 
FileDataValidator onePerson = new FileDataValidator();
try {
onePerson.build(lineData);
} catch(InvalidDataException e){
//该怎么办?
}

以下是课程代码:

  public FileDataValidator(){
//也许你需要一些代码在这里,也许不是
}

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()方法,您调用它来查看它是否正确,但异常似乎是正确的方法我的构建功能。



变体4:



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



这种方式遵循JaxB和JaxRS的工作方式,这与你所拥有的情况类似。


  1. 一个外部的数据源 - 你有一个文件,他们有一个收到的XML或JSON格式的消息。

  2. 构建对象的代码 - 您有代码,他们的代码库按照各种JSR中的规范工作。

  3. 验证不与建立对象。

调用代码:

  String [] lineData = readLineData(); 
Person onePerson = new Person();
FileDataUtilities util = new FileDataUtilities();
try {
util.build(onePerson,lineData);
util.validate(onePerson);
} catch(InvalidDataException e){
//该怎么办?
}

以下是数据生命的类代码:

  public class Person {
private Name name;
私人年龄;
私人镇镇;
...更多的东西在这里...
}

实用程序代码来构建和验证:

  public FileDataValidator(){
//也许你需要一些代码在这里,可能不是
}

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);
返回true;
}
catch(InvalidFormatException e)
{
throw new com.myco.myapp.errors.InvalidDataException(e.getMessage());
}

}


Something I've always been curious of

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

Is is not advisable to include the try/catch block within my Constructor? I know I could have the Constructor throw the Exception back to the caller. What do you guys prefer in calling methods like I have done in Constructor? In the calling class would you prefer creating an instance of FileDataValidator and calling the methods there on that instance? Just interested to hear some feedback!

解决方案

In the code you show, the validation problems don't communicate back to the code that is creating this object instance. That's probably not a GOOD THING.

Variation 1:

If you catch the exception inside the method/constructor, be sure to pass something back to the caller. You could put a field isValid that gets set to true if all works. That would look like this:

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;
}

Variation 2:

Or you could let the exception or some other exception propagate to the caller. I have shown it as a non-checked exception but do whatever works according to your exception handling religion:

public FileDataValidator(String[] lineData){

    this.lineData = lineData;
    removeLeadingAndTrailingQuotes();

    try
    {
        validateName();
        validateAge();
        validateTown();
    }
    catch(InvalidFormatException e)
    {
        throw new com.myco.myapp.errors.InvalidDataException(e.getMessage());
    }

}

Variation 3:

The third method I want to mention has code like this. In the calling code you have to call the constructor and then call the build() function which will either work or not.

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

Here is the class code:

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());
    }

}

Of course, the build() function could use a isValid() method that you call to see if its right but an exception seems the right way to me for the build function.

Variation 4:

The fourth method I want to mention is what I like best. It has code like this. In the calling code you have to call the constructor and then call the build() function which will either work or not.

This sort of follows the way JaxB and JaxRS work, which is a similar situation to what you have.

  1. An external source of data - you have a file, they have an incoming message in XML or JSON format.
  2. Code to build the objects - you have your code, they have their libraries of code working according the specifications in the various JSRs.
  3. Validation is not tied to the building of the objects.

The calling code:

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?
}

Here is the class code where the data lives:

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

And the utility code to build and validate:

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());
    }

}

这篇关于尝试/抓住建设者 - 推荐做法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆