我一直对
感到好奇的事情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的实例并在该实例上调用那里的方法吗?只是有兴趣听一些反馈!
答案 0 :(得分:21)
在您显示的代码中,验证问题不会与创建此对象实例的代码进行通信。这可能不是一件好事。
变体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:
我想提到的第三种方法有这样的代码。在调用代码中,您必须调用构造函数,然后调用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()
方法来查看它是否正确但异常对我来说是构建函数的正确方法。
变体4:
我想提到的第四种方法是我最喜欢的方法。它有这样的代码。在调用代码中,您必须调用构造函数,然后调用build()
函数,该函数将工作与否。
这种方式遵循JaxB和JaxRS的工作方式,这与您的方式类似。
主叫代码:
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 ...
}
用于构建和验证的实用程序代码:
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());
}
}
答案 1 :(得分:3)
您应该考虑静态工厂模式。使所有参数构造函数成为私有的。提供静态FileDataValidator(args ...)方法。这接受并验证所有参数。如果一切正常,它可以调用私有构造函数并返回新创建的对象。如果有任何失败,抛出一个Exception来通知调用者它提供了错误的值。
我还必须提到这一点: catch(例外e){ printSomeThing(E); }
你可以用例外来做最致命的反模式。是的,您可以在命令行上读取一些错误值,然后呢?调用者(提供错误值的人)没有得到错误值的通知,程序执行将继续。
答案 2 :(得分:2)
我倾向于通过知道如何处理它们的代码来处理异常。在这种情况下,我假设创建FileDataValidator的代码位知道如果文件数据无效将会发生什么,并且异常应该在那里处理(我主张传播给调用者)。
在讨论最佳实践时 - 类名FileDataValidator闻起来像我。如果您正在创建的对象存储文件数据,那么我将其称为FileData - 可能使用validate方法?如果您只想验证文件数据,那么静态方法就足够了。