2011-05-22 7 views
6

大規模なソフトウェア実装では、APIの設計と実装の分離が推奨されることがよくあります。しかし、どこかに再接続する必要があります(つまり、実装をAPIに再接続する必要があります)。APIとインプリメンテーションの分離は合計する必要がありますか?

次の例では、インスタンスオブジェクトを介して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の位置など)を取得するための具体的な方法がありますが、具体的なArrayListの実装方法に固有のものであるため、Collectionに公開されていません。

私はまた、それぞれが単一の具体的な実装を備えた巨大なディレクトリのディレクトリを持つプロジェクトを見てきました。それらのそれぞれは、完全に無意味な "ふり"の抽象化のような実際には論理抽象化を提供していません。

3

OSGiでよく使用される手法の1つは、APIを実装とは別のモジュールに入れることです。 APIは、実装自体への参照を直接避けてコンパイルする必要があります。

+0

これはOSGiの絶対的な必要なのか、それともよい方法でしょうか? – JVerstry

+0

iPOJOのようなフレームワークを必要に応じて使用するには、すべてのケースでそれを行う必要はありません(そして私はそうしません) –

2

PeterさんとSteveさんの答えは十分ですが、私はこれまでにインターフェイスや抽象クラスを1つしか実装していないのであれば、抽象化の目的を破るようにインターフェースや抽象クラスを持っています。
私は実際に理解していませんでした。Separationを抽象クラスとして実装した理由は、SeparationImpl自体がAPIクラスであるか、別の実装がある場合ですSeparationはinetrfaceとなります。あなたのインターフェースを実装する別の抽象クラスを持っていて、その抽象クラスから継承するSeparationImplを持っています。

:サンプルのクラス階層はちょうど私がユニットテストの目的に言及う他の著者からの良い点に

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

プロダクション実装が1つだけでも、ABCやインターフェイスはまだ良いことが多いです。第一に、彼らは懸念のきれいな分離を強制する。第二に、モックによる簡単なユニットテストが可能です。 –

+0

私は、APIのインスタンス化にアクセスする必要があり、API自体からAPIを提供する方法があることを説明しようとしていました。私は同意する、これはインターフェイスでのみ行われている可能性があります。 – JVerstry

+0

@Oli Charlesworth - 私たちは具体的なクラスを模擬することができ、少なくともモックの目的のためのインターフェースを持つ必要はありません。 – Premraj

1

追加の標準コレクションライブラリのよう

interface Separation --> AbstractSeparation --> SeparationImpl 

ようになります。インターフェイスをクラスの中に入れておくと、オブジェクトをモックアップするのが非常に簡単になります。

関連する問題