最佳实践 - 异常处理

时间:2014-12-31 18:21:32

标签: java performance exception

我不知道在我的案例中最好的做法是什么:

1:

public class garage {

    private List<Car> cars = new ArrayList<Cars>();

    public String getCarSeatSomething(String carName, String brandName) {
           for(Car car : cars){
              if(car.getName().equals(carName)){
                 Seats seats = car.getSeats();
                 List<Brand> brands = seats.getBrands();
                 for(Brand brand: brands ){
                    if(brand.getName().equals(brandName)){
                       return brand.something();
                    }
                 }
              }
           }
           return null;
     }
         ...
}

我有很多这样的方法,所以我会用这个解决方案有一些冗余的代码。

而且,在我的程序中,我们找不到汽车并不“正常”,所以我认为我必须使用Exception no?

2:

public class Garage {

    private List<Car> cars = new ArrayList<Car>();

    public Something getCarSeatSomething(String carName, String brandName) {
           Car car = searchCar(carName);
           if(car == null) 
              return null;
           else{
              Seats seats = car.getSeats();
              return seats.getSomething(brandName);
           }  
    } 
        ...
}


public class Seats {

    private List<Brand> brands = new ArrayList<Brand>(); 

    protected Something getSomething(brandName){
              Brand brand = searchBrand(brandName);
              if(brand == null)
                 return null;
              else
                 return brand.something();
    }
      ...
}

Garage类的每个方法的冗余代码少,代码少,因为搜索只在searchBrand和searchCar中进行。 但我总是存在异常问题。

所以,我的最后一个解决方案是在searchBrand和searchCar方法中抛出异常,在使用searchBrand / searchCar的所有方法(如getCarSeatSomething)中添加throws,并在使用这些方法时尝试... catch(如getCarSeatSomething)

这是对的吗? 如果没有,你有更好的想法吗?

3 个答案:

答案 0 :(得分:0)

看起来汽车名称和品牌名称将由用户提供输入。在这种情况下,您应该期望用户提供不存在的名称。这不是例外。返回null并在顶层向用户返回错误消息。你可能试图“获得”某些东西而不是完全得到它似乎是合理的。 null在这里是合适的。但请确保您在整个应用程序中对此行为保持一致并记录它。

答案 1 :(得分:0)

描述情况:您有一个精心设计的数据层次结构,可能具有链接访问权限:

x.getLiat().get(3).getAs().lookupB("a1").getC();

这可能会导致设计处理可疑的NullPointerExceptions(丑陋)或Excptions。

Java 8 建议Optional<T>在一个表达式中显式处理否则可能为null。

x.getA().orElse(a).getB().orElseThrow(() -> new XException()).getC();

更好的是使用java 8的流,通过过滤,映射,查找任何/第一个功能。

private List<Car> cars = new ArrayList<>();

public Optional<String> getCarSeatSomething(String carName, String brandName) {
    return cars.stream()
        .filter((car) -> car.getName().equals(carName))
        .flatMap{(car) -> car.getSeats())
        .flatMap((seats) -> seats.getBrands())
        .filter((brand) -> brand.getName().equals(brandName))
        .findFirst();
 }

答案 2 :(得分:0)

如果实体必须包含特定属性,则该属性的getter方法应该在实体无法提供属性时抛出异常。

如果实体包含该属性是可选,则getter方法不应抛出异常。

某些情况将涉及两种情况,其中在某些情况下,对属性的访问是强制性的,而在其他情况下,它是可选的。然后你应该提供两个“getter”方法,一个如果不能返回属性则抛出异常,另一个是Optional值。对于可选的getter方法,我建议使用 getEntity 的方法命名约定,对于可选的getter方法,我建议使用 findEntity

如果实体必须包含特定属性且getter方法无法完成请求,则表明您的实体格式不正确。如果您的实体因为无法返回强制属性而抛出异常,那么您就会对如何创建实体产生错误或问题。

永远不应在没有强制属性的情况下创建实体。构造函数和工厂应该强制执行强制属性。对于必须创建且未完全形成的实体(如数据访问对象),应在使用之前对实体应用单独的验证。或者将您的域实体和DAO分离为单独但等效的类型。