2012-02-02 5 views
4

を持つ被験者はすでにそれを言う:OOP-デザイン:インタフェース・メソッドの実装に依存するパラメータ

私は、次の設計の問題について今考えています:私は様々な方法が含まれている特定のタイプのオブジェクトのためのインタフェースを定義。 今、私は問題があります。このインタフェースの実装には、別の/別のメソッドパラメータが必要です(実装されているため、これが必要になります)。すべてインターフェイスに組み込むことができません。 - 実施。

インターフェイスの実装に独自のプロパティファイルが付属していて、そこから追加のパラメータを読み込むことができますが、これらのパラメータを実行時に渡す必要がある場合はどうなりますか? DocumentBuilderFactoryのようなJDK-クラスは、この は、この問題を解決するための実行可能なアプローチのように思えるsetAttribute(String attName, Object attValue)のような方法を提供することにより、非常に似た何かをやっているので、 -

は現在、私は唯一のこの問題を克服するために Map<String, Object> parametersに渡すと考えることができます。 それにもかかわらず、私は他の人がこのような問題をどのように解決するのか、別の考え方に興味がありますか?

私の場合、私はベースインターフェイスのメソッドからNotImplementExceptionを投げなければならないため、インターフェイスから派生してメソッドを追加したくありません。

はUPDATE

地図・アプローチの最終的な問題何ができますか?クラスを実装すると、追加のパラメータを使用できない場合でも、クラスを完全に無視することができます。 Mapは、目的のパラメータ名が含まれているかどうかをチェックし、値の型をチェックし、有効な場合は使用し、そうでない場合は例外をスローします。 私も..一般的なアプローチであると思われるので、これは、抽象クラスJAXBContextのために使用されて見てきました

UPDATE:私は見ていけないため、マップのアプローチのために行くことに決めた

明白な欠点があり、JDKでも使用されています。(はい、これは必ずしも意味があるとは限りません:) 私はこの質問に対する回答を受け入れることができないので、私はちょうどupvoteします。あなたのご意見ありがとうございます!

に関して、

--qu

+0

この情報は、メソッドが必要とするものか、オブジェクトがそのアクションを実行するために必要なものですか?具体的な例を挙げてください。 ** Map **を使用することは、デザインの決定には恐ろしいものです。 –

+0

@MaurícioLinhares私は、このソリューションは最適ではないことを認識しています(なぜこの質問をしたのですか)。しかしDocumentBuilderFactoryを例に取ってみましょう。インターフェイスはすべての可能なDOMパーサーで同一ですが、DOMパーサー実装では異なる機能/あなたが決してインタフェースに取り入れることのできないパラメータを、実行時に何らかの方法でそれらのパラメータを渡す方法が必要です。私はJDKがこれを解決する方法を述べました... – quaylar

+1

これは**初期化**プロセスです。工場の唯一の目的は、その作業を行う準備ができている新しいオブジェクトを作成することです**インターフェース**はまったく変更されません。あなたが望むのは何か他のものです。これを**インターフェースメソッド**に追加したいと思っています。あなたが望むものが実際に初期化の間にオブジェクトをセットアップするならば、これらのオブジェクトをコンストラクタのパラメータにしてください。 –

答えて

1

はあなたの(スーパー)のインターフェイスを拡張するサブインターフェイスを設計することができませんでしたか? いずれにしても、実装に応じて異なるパラメータを持つメソッドが必要な場合は、設計上の問題が発生します。

編集:コマンドオブジェクトを使用して は」それが簡単に委任し、シーケンスまたはメソッドがで呼び出しを実行する必要があり、一般的なコンポーネントを構築することができます:あなたはCommandパターンから利益を得ることができる:

interface CommonBehaviour 
{ 
    void methodA(int aParam); 
} 

interface SpecificBehaviour extends CommonBehaviour 
{ 
    void methodB(int aParam, int anotherParam); 
} 

class SpecificBehaviourImpl implements SpecificBehaviour 
{ 
    void methodA(int aParam) 
    { 
     //do something common 
    } 

    void methodB(int aParam, int anotherParam) 
    { 
     //do something specific 
    } 
} 

CommonBehaviour myObj = new SpecificBehaviourImpl(); 

EDITを明確にするためのコードメソッドの所有者またはメソッドのパラメータを知る必要なく、選択した時間。「 (ソース:ウィキペディア)私はMapアプローチはどんな良いとは思わない

、私はあなたが任意のパラメータの数とタイプを持つことができるようになる、既存のコードの修正としてそれを受け入れますが、なしあり正式なチェック!変数、ランタイム、状態を指定して、共通の動作(インターフェイスメソッド)を定義しようとしています。

+0

私はこれを実行しましたが、実装がベースインターフェイスのメソッドを実装できないため、まだ実装する必要がありますが、 NotImplementedException - あまりにも好きではないデザイン。 – quaylar

0

問題を逆転し、これらのオブジェクトのユーザーに対して、追加のパラメータ?

したがって、共通インターフェイスを実装するこれらのオブジェクトをインスタンス化するときには、 (例えば、それらのコンストラクタに)必要な追加パラメータにアクセスする方法を提供するオブジェクトです。

あなたのインターフェースにはパラメータ 'a'を取る 'doSomething'メソッドがありますが、この 'doSomething'メソッドの中に 'b'が何であるかを知る必要がある実装があります。この情報を取得するには、コンストラクタに渡したオブジェクトのgetBを呼び出します。

+0

もう少し詳しいことを教えてください。私はまだアイデアをまだ得ていません.. – quaylar

+0

@quaylar - それはまったく役に立ちますか? – sje397

+0

私にとっては、これは単に間接的な層を追加するようです。 interface-methodのクライアントは、可能なパラメータのセットがあることを知っていますが、すべての実装がそれらのすべてを「理解」しているわけではありません。 オブジェクト作成時に、これらのパラメータは不明なので、コンストラクタ経由で渡すことはできません。彼らはインターフェイスクライアントによって受信されるので、あなたが提案しているように委譲オブジェクトを指定する方法もありません。 – quaylar

0

可能な引数のスーパーセットを表すを表すパラメータオブジェクトを導入する必要があります。

+0

もちろん、これは最も単純なバリアントです。サブクラス化すると、デザインをより読みやすくすることができます。 –

1

インターフェイスのポイントは、すべての実装に共通のものがあることです。これを試みることによって、インターフェースが存在する全理由を破壊することができます。

これを絶対に行う必要がある場合は、私が以前に使った方法と同じように簡単です。

他の言語に堪能ではないので、私の答えはC++です。私はこれもjavaで実装する方法があると確信しています。

SomeMethod(void* parameterData);

void* parameterDataあなたのデータを含む構造体へのポインタです。各実装では、受信していることを知っています。列挙型を使用して、どのような種類のデータを受け取っているかを伝えることもできます。

SSomeData* data = (SSomeData)parameterData

EDIT:IParameterData

別のアプローチは、パラメータのための新しいインターフェイスを作成することです。
このインターフェイスの内部には、GetParameter(name)SetParameter(name)という2つの方法があります。
プライマリインターフェイスの実装ごとに、IParameterDataの実装を作成します。

私はそれがあなたの代わりに

+0

さて、Javaに翻訳されて、これは私の質問で述べたアプローチだろう。 – quaylar

+0

すみません。あなたが言ったことは、私が言ったことのJava版であることに気付かなかった。別のアプローチで編集を準備しています。 – Sanctus2099

+0

ありがとうございました。これはマップを直接渡すのと非常に似ています。 – quaylar

0

を役に立てば幸い、私はあなたのニーズに合わせてインタフェースのメソッドを曲げるようにしようというし、あなたの問題への適切な設計パターンを見つける検討します。まずStrategy Patternをご覧ください。

1

あなただけの独自の特定に必要なパラメータを指定して、各相続を初期化し、インターフェイスメソッドがのように、パラメータなしのままにさせてください:

インタフェースRunnable

public interface Runnable { 
    public abstract void run(); 
} 

が実装:

public class MyRunnable { 

    private final String myConcreteString; 

    public MyRunnable(String myConcreteString) { 
     this.myConcreteString = myConcreteString; 
    } 

    public void run() { 
     // do something with myConcreteString 
    } 
} 
+1

これらのパラメータは、オブジェクト作成時には分かっていません... – quaylar

関連する問題