2009-06-24 89 views
6

我有以下API:的Java API休息

public class MyApiImpl { 

    public void method() throws MyException { 
    if (C1) { 
     throw new MyException("c1 message"); 
    } else if (c2) { 
     throw new MyException("c2 message"); 
    } 
    ... 
    } 
} 

你:

public interface MyApi { 

    /** 
    * Performs some stuff. 
    * @throws MyException if condition C1 
    */ 
    public void method() throws MyException; 
} 

現在我在我的API實現執行以下修改

public class MyApiImpl { 

    public void method() throws MyException { 
    if (C1) { 
     throw new MyException("c1 message"); 
    } 
    ... 
    } 
} 

被替換將此視爲API損壞?

由於MyExcepiton被「新」條件拋出,客戶端的代碼仍然可以編譯,但API javadoc定義的方法約定不受重視。

如果只更新我的API jar文件,客戶端應用程序仍然可以工作,但取決於客戶端捕獲異常的方式,應用程序行爲可能會發生很大的變化。

對此你有什麼看法?

回答

7

是的,當C1沒有發生時,通過拋出異常來打破界面的契約。

作爲一個經驗法則,模糊接口契約,越不容易破壞:)如果接口不是用明確的C1來定義的,但是更籠統地說,它提供了更多靈活性。

6

我的觀點是,您不應該更改文檔中由API定義的合同。如果您需要新的行爲,您應該創建一種新方法,客戶可以調用這種方法來反映這種新行爲,或者b)與客戶討論需要更改並使他們意識到這一點。

這真的可以兩種方式,它是你和你的客戶之間,你的方法將是什麼。

1

它很大程度上取決於c2是什麼。它是否在原有合同的邏輯範圍之內?如果是這樣,通過拋出MyException來滿足合同。如果沒有,那麼你可能需要拋出一種新的異常。

我應該指出,我不是檢查異常的巨大粉絲。最終,強迫某人處理異常並不一定會使他們的代碼變得更好或更安全(事實上,它可能會產生相反的效果,因爲他們可以不經意地吞下虛假的異常)。

1

我會說「不」,沒有API破損,除非MyException是一個RuntimeException。那就是。

不管怎樣,我會繼承MyException的條件C2

而這兩個條件C1和C2應該是「例外」恕我直言,我不會讓拋出異常

1

這是一個破損的習慣。 API是通過語言結構實施還是簡單記錄是無關緊要的。

這種破損是否導致客戶端代碼出現問題是另一回事。這可能是因爲你正在修理一個缺陷,需要用這種方法來覆蓋案例C2來修復它。從這方面來說,客戶端代碼開發人員可能會很高興你已經做出了這樣的改變(假設他們目前沒有以這種方式解決這個問題,那麼面對改變時就會發生這種情況!)

1

我認爲這裏的問題在於你使接口的一部分,實現的具體條件。如果「C1」條件只是您的實現的一部分,那麼您可以簡單地創建一個新的實現,在「C1」或「C2」上引發異常而不會中斷接口。