2014-12-31 83 views
1

我不知道什麼是在我的情況的最佳實踐:最佳實踐 - 異常處理

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

較少冗餘代碼和更少的代碼,因爲搜索僅在searchBrand和searchCar。 但我總是有例外的問題。因此,我的最後一個解決方案是在searchBrand和searchCar方法中拋出異常,在使用searchBrand/searchCar的所有方法(如getCarSeatSomething)上添加拋出,並嘗試... catch當我使用這些方法時(比如getCarSeatSomething )。

這是正確的嗎? 如果不是,你有更好的想法嗎?

+1

編寫代碼以使用值 - 並避免出現異常,除非出現異常情況(通常不能在直接級別恢復)。基本上,問這些:當請求不能被執行時會發生什麼?誰是過錯?對此有何期待? – user2864740

+0

如果我沒有找到一輛車,我必須記錄它。這是呼叫者的錯,而不是包含汽車的對象。 – kaoziun

+4

「避免**異常**,**除**當發生**異常**時」 - - 真棒:-) – Leo

回答

0

它看起來像汽車名稱和品牌名稱將是用戶提供的輸入。在這種情況下,您應該期望用戶提供不存在的名稱。這並不例外。返回null並在頂層,向用戶返回錯誤消息。看起來合理的是,你可能會試圖「獲得」某些東西,而不是完全理解它。 null在這裏是適當的。但要確保你在應用程序中的這種行爲是一致的,並且記錄它。

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

如果一個實體必須包含特定屬性,那麼吸除該屬性的方法應該拋出一個異常,如果實體不能提供該屬性。

如果它是可選對於包含該屬性的實體,則getter方法不應引發異常。

一些情況將涉及這兩種情況,在某些情況下,對屬性的訪問是強制性的,在其他情況下,它是可選的。然後你應該提供兩個「getter」方法,一個如果屬性不能返回就會拋出異常,另一個是可選值。對於可選的getter方法,我推薦使用getEntity的方法命名約定用於強制性的getter方法,findEntity

在實體必須包含特定屬性並且getter方法無法完成請求的情況下,您的實體格式不正確。如果您的實體拋出異常,因爲它不能返回強制屬性,那麼您在創建實體時會遇到一些錯誤或問題。

實體決不能創建沒有強制屬性。構造器和工廠應該強制強制屬性。對於必須創建且未完全形成的實體(如數據訪問對象),在使用實體之前,應將單獨的驗證應用於實體。或者將你的域實體和DAO分離成獨立但等同的類型。