2011-05-22 28 views
6

在大型軟件實現中,通常建議將API設計與其實現分離。但在某個地方,它們必須重新連接(即,實施必須重新連接到API)。API和Implementation之間應該是完全分離的嗎?

以下示例顯示了一個API設計,並通過實例對象的執行的調用:

import java.util.List; 

public abstract class Separation { 

    public static final Separation INSTANCE = new SeparationImpl(); 

    // Defining a special list 
    public static interface MySpecialList<T> extends List<T> { 
     void specialAdd(T item); 
    } 

    // Creation of a special list 
    public abstract <T> MySpecialList<T> newSpecialList(Class<T> c); 

    // Merging of a special list 
    public abstract <T> MySpecialList<? extends T> specialMerge(
     MySpecialList<? super T> a, MySpecialList<? super T> b); 

    // Implementation of separation 
    public static class SeparationImpl extends Separation { 

     @Override 
     public <T> MySpecialList<T> newSpecialList(Class<T> c) { 
      return ...; 
     } 

     @Override 
     public <T> MySpecialList<? extends T> specialMerge(
      MySpecialList<? super T> a, MySpecialList<? super T> b) { 
      return ...; 
     } 

    } 

} 

有人會說,API應該不是指實現代碼。即使我們通過單獨的文件將API代碼與實現分開,通常也必須在API中導入實現代碼(至少是類名)。

有一些技術可以通過使用完全限定名稱的字符串表示來避免這種引用。該類用該字符串加載,然後實例化。它使代碼更復雜。

我的問題:從實現代碼中完全分離或隔離API代碼有什麼好處嗎?或者,這僅僅是純粹主義者試圖達到完美而沒有什麼實際好處的嘗試?

回答

6

我一直理解要求從執行單獨的接口意味着你不與什麼混音實施如何。所以在上面的例子中,混合api和實現將意味着在api中公開一些特定於SeparationImpl如何實現您的API的內容。

作爲一個例子,看看如何在各種集合類中實現迭代。還有更具體的方法可以檢索特定集合中的元素(例如,通過在ArrayList中的位置),但這些方法不會在Collection中公開,因爲它們特定於如何實現具體的ArrayList。我也看到有大量接口目錄的項目,每個接口都有一個具體的實現,並且每個接口都在其具體實現中機械地複製每個方法,這看起來像一個完全沒有意義的「假裝」抽象,如同它實際上並不提供任何邏輯抽象。

3

OSGi中經常使用的一種技術是將API放在一個單獨的模塊中用於實現。 API應該自己編譯,避免直接引用任何實現。

+0

這是OSGi絕對必要還是僅僅是良好的做法? – JVerstry 2011-05-22 20:03:16

+0

要使用像iPOJO這樣的框架是必要的,但是你不必在所有情況下都這樣做(而且我不這樣做) – 2011-05-22 20:09:06

2

Peter's和Steve的答案已經足夠,但我想補充更多的內容 - 如果您只有單一的接口或抽象類的實現,那麼它就沒有任何接口或抽象類,因爲它無法實現抽象的目的。
在你的情況我真的不明白 - 爲什麼你實現Separation作爲一個抽象類,而SeparationImpl本身可以是API類,或者如果你有不同的實現Separation可以是inetrface,如果你有一些共同的功能,那麼你可以有另一個抽象類實現你的接口,然後繼承這個抽象類。樣本的類層次看起來像

interface Separation --> AbstractSeparation --> SeparationImpl 

就像標準的集合庫

interface List --> AbstractList --> ArrayList 
+0

即使只有一個生產實現,ABCs和接口仍然是一件好事,首先,他們強化了對問題的清晰分離。其次,它們允許通過mock輕鬆進行單元測試。 – 2011-05-22 19:30:36

+0

我想說明一個事實,即有時需要訪問API的實例,一種方法是從API本身提供它。我同意,這可能只是通過接口完成的。 – JVerstry 2011-05-22 20:06:09

+0

@Oli Charlesworth - 我們可以嘲笑具體的類,至少不需要爲嘲笑目的設置接口。 – Premraj 2011-05-23 04:59:04

1

附加到好點從其他作者的我就更不用說了單元測試目的:

模擬對象的時候,如果接口不是類,就更容易。

相關問題