我应该在课堂内还是外面处理这些例外?

时间:2016-11-11 22:38:50

标签: java

我的Person类有两种不同的方法,一种是在创建Person对象之前处理可能的异常,另一种是在Person类中处理它们。

方法1

import java.time.LocalDate;

public class Person {
    String name;
    LocalDate birthDate;

    public Person(String name, LocalDate birthDate) {
        this.name = name;
        this.birthDate = birthDate;
    }

    public void setBirthDate(LocalDate birthDate) {
        this.birthDate = birthDate;
    }
}
import java.time.LocalDate;
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);

        System.out.print("\tName: ");
        String name = scanner.nextLine();

        System.out.print("\tBirth date (YYYY-MM-DD): ");
        String birthDate = scanner.nextLine();
        String[] info = birthDate.split("-");

        // This may thrown DateTimeException, if someone gives an invalid year, month or day.
        birthDate = LocalDate.of(Integer.parseInt(info[0]), Integer.parseInt(info[1]), Integer.parseInt(info[2]));

        Person mike = new Person(name, birthDate);
    }
}

方法2

import java.time.LocalDate;

public class Person {
    String name;
    LocalDate birthDate;

    public Person(String name, String birthDate) {
        this.name = name;
        this.setBirthDate(birthDate);
    }

    public void setBirthDate(String  birthDate) {
        String[] info = birthDate.split("-");

        // This may thrown DateTimeException, if someone gives an invalid year, month or day.
        birthDate = LocalDate.of(Integer.parseInt(info[0]), Integer.parseInt(info[1]), Integer.parseInt(info[2]));
        this.birthDate = birthDate;
    }
}
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);

        System.out.print("\tName: ");
        String name = scanner.nextLine();

        System.out.print("\tBirth date (YYYY-MM-DD): ");
        String birthDate = scanner.nextLine();

        Person mike = new Person(name, birthDate);
    }
}

我是否应该期望所有Person客户端都会导入java.time.LocalDate并自行创建日期,或者我应该将此工作封装在Person中,客户端只会提供String }?

3 个答案:

答案 0 :(得分:0)

我应该处理它内部或我称之为setter的任何地方的异常吗? Java有关于此的一些规则吗?

如果任何数据无效,最好的做法是在构造对象本身时抛出异常以确保对象处于正确的状态。

此外,如果可以使用setter修改数据,则需要进行验证并抛出异常以确保对象再次处于正确状态。

public class Person {
    String name;
    LocalDate birthDate;

    public Person(String name, LocalDate birthDate) {
       //If input data is NOT valid,
       //throw new IllegalStateException("Invalid name and birthDate");
      //Now, if input data is valid, assign them to ref variables
      this.name = name;
      this.birthDate = birthDate;
    }

    public void setBirthDate(LocalDate birthDate) {
       //If input data is NOT valid,
       //throw new IllegalStateException("Invalid name and birthDate");
       this.birthDate = birthDate;
    }
}

答案 1 :(得分:-1)

遇到这种问题时,你应该问自己两个问题

  1. 这门课的目的是什么?
  2. 我可以在哪里处理异常?
  3. 对于这种情况,此类是Person的模型。 POJO模型应该假设它们的依赖关系是正确的(LocalDate birthDate)。假设此模型的客户端输入了正确的输入,您可以在其方法上抛出异常。

    public Person(String name, LocalDate birthDate) throws DateTimeException {
            this.name = name;
            this.birthDate = birthDate;
        }
    
    public void setBirthDate(LocalDate birthDate) throws DateTimeException {
        this.birthDate = birthDate;
    

    现在异常处理由此Person类的客户端处理。

    try{
        DateTimeFormatter germanFormatter = DateTimeFormatter.ofLocalizedDate(
                FormatStyle.MEDIUM).withLocale(Locale.GERMAN);
    
        LocalDate newYear = LocalDate.parse("01.01.2016", germanFormatter);
        Person person = new Person("Joe", newYear);
    
    }catch (DateTimeException e){
        // Do something about it
    }
    

答案 2 :(得分:-1)

由于我不同意所提供的任何一个答案,我将解释如何做到这一点。

首先,当您描述问题时,看起来用户输入将是String,其中代表有效的LocalDate

这里适用的常见模式是名为提前投掷,迟到的模式。由于您的Person的客户正在处理用户输入,他们有第一次机会抛出/处理问题并获得最多信息(例如,他们可以尝试以他可以转换他的方式引导用户输入有效的LocalDate)。

Person为什么要关心将String转换为LocalDate?它应该只处理Person相关的状态和行为。他们也可以执行验证,但这些都是业务特定的检查,比如在他的生日是未来时不允许构建Person对象(如果这没有意义,可能就是那些)。在这种情况下,它绝对不应该抛出DateTimeException而是更合适的用户定义的异常。

public Person(String name, LocalDate birthDate) throws InvalidBirthDateException {...}
public void setBirthDate(LocalDate birthDate) throws InvalidBirthDateException {...}

上述合同明确规定Person类接受LocalDate birthDate并让客户处理必要的数据转换,但它也声明可能有一些日期不代表有效对于某人的birthDate,在这种情况下,该方法将抛出客户端可以捕获并尝试修复的自定义异常。

我的观点是:让客户处理无效输入,因为他们可以修复它。例外情况旨在尽可能处理。想象一下如何处理Person内的错误日期。最多只返回一条错误消息,客户端仍然需要添加用户输入特定逻辑来捕获并尝试恢复。不要假设Person知道用户输入的来源(它可能是命令行,GUI或它可能是文件)。