2012-02-23 27 views
1

私は以下のクラスとインターフェイスを持っています。基本的にIOldインターフェイス(これは廃止予定)をフリーズし、ユーザーにIOldと同じメソッドを含むINewインターフェイスを使用させたいと考えています。しかし、INewメソッドMeth3はIOld Meth2と同じ機能を表しますが、戻り値のタイプが異なります。これらをよりよく区別するために、このデザインは適切であると考えました。私の質問は、これは良いコーディング方法と考えられますか?派生クラスのインターフェイスメソッドを実装する抽象基本クラス

注:IOldとINewは、別々のアセンブリに存在します。 NewClassは、クライアントがINewインターフェイス経由で接続するリモート(MarshalByRef)オブジェクトとして公開されるため、どのような方法でもIOldを参照することはできません。新しいクライアントがIOldアセンブリを参照しないようにしたい。

public interface IOld 
{ 
    void Meth1(); 
    double Meth2(int input); 
} 

public interface INew 
{ 
    void Meth1(); 
    float Meth3(int input); 
} 

public abstract class BaseClass 
{ 
    public virtual void Meth1() 
    { 
    } 

    public virtual double Meth2(int input) 
    { 
     throw new NotImplementedException(); 
    } 
} 

public class OldClass 
: 
    BaseClass, 
    IOld 
{ 
    public override double Meth2(int input) 
    { 
     return 0; 
    } 
} 

public class NewClass 
: 
    BaseClass, 
    INew 
{ 
    public float Meth3(int input) 
    { 
     return 0; 
    } 
} 

答えて

2

私はこのような何か試してみた:それは殺すことによって、それを破ることよりも、彼らは自分のコードを更新する必要があり、開発者に通知するために、非推奨の方法フラグに、より良い習慣と考えられています

public class OldClass : BaseClass, IOld 
{ 
    public override double Meth2(int input) 
    { 
     return 0.0; 
    } 
} 

public class NewClass : OldClass, INew // now implements IOld and INew using the Method2() from OldClass 
{ 
    [Obsolete("This method is deprecated . Use Method3() instead.")] 
    public override double Meth2(int input) 
    { 
     return base.Meth2(input); 
    } 
    public float Meth3(int input) 
    { 
     return return 0.0f; 
    } 
} 

を古い方法。

+0

+1は - だけでなく少し編集の自由を取った - SOZ !! :-) –

+0

ありがとうございました。はい、私は非推奨としてインターフェイスをマークするが、基本的なデザインを指摘したいと思った。私が作ったはずの点は、NewClassはリモートオブジェクトとして公開され、INewインターフェイス経由でそれを受け取ったクライアントがIOldアセンブリを取得できないため、どのような方法でもIOldを参照できないことです。私はそれに応じて私の質問を更新しました。 – Jeb

3

座って座って、しっかりしたベースでピラミッドを構築してください。あなたが物事を設定したやり方で、抽象基本クラスとインターフェースは、同じコンセプトを達成するための競合する方法です。あなたはこれを主に古いものと新しいものとを容易にするためにしていますが、これを行うときにはかなりファンキーな依存グラフになります。

あなたが書いたものでは、あなたの唯一の問題は、同じ署名のメソッドです。この問題がなければ、古いインターフェイスを簡単に拡張して、問題を解決することはできません。新しい方法でそのメソッドが変更された場合は、それがリファクタリングの変更(許容)か全く異なる結果ですか?つまり、古いクライアントは新しいクライアントを呼び出すことができますか?そうであれば、そのメソッドを別のインターフェース上に持つ必要はありません。

メソッドを非推奨にして、古いメソッドを失うことに気づくようにしてください。また、それが文書化されていることを確認してください。

+0

ありがとうございました。いいえ、古いクライアントは新しいクライアントを呼び出すことはできません。私が作ったはずの点は、NewClassはリモートオブジェクトとして公開され、INewインターフェイス経由でそれを受け取ったクライアントがIOldアセンブリを取得できないため、どのような方法でもIOldを参照できないことです。 – Jeb

+0

ソースコントロールを使用していますか?ブランチする能力がありますか?古いクライアントは、コードが更新され、新しいものが常に新しいものになるまで古いものを使い続けるように聞こえるので、私は尋ねます。それが本当であれば、コードを分岐して古いものを保守ブランチに、新しいものを現在のブランチに保存します。メンテナンスブランチはバグ修正のためのものです。最後のステップでは、バージョニングを考慮して、ただ1つのクライアントにバージョン1のDLLともう1つのバージョン2を与えることです。単一のクライアントが両方の時間を必要とする場合は唯一の問題です。そうでない場合、それはソフトウェアの変更の一部にすぎません。 –

+0

残念ながら、最後の手段がない限り、コードを再コンパイルするようにクライアントに依頼することはできません。したがって、私たちはIOldの下位互換性が必要です。しかし、私たちはIOldをサポートするつもりはなく、INewにはバグ修正が行われ、再コンパイルするようアドバイスされます。古いクライアントは、2 apisを介してリモートクライアントからのリモート呼び出しに対処するサーバーを除いて、古いインタフェース/新しいクライアントを新しく使用し続けます。 – Jeb

2

新しいインターフェイスを作成する代わりに、少し違う名前で新しいメソッドを追加することをお勧めします。

だから古いインターフェースは、例えば次のようになります。

public interface IOld 
{ 
    void Meth1(); 
    [Obsolete("Use Meth22 instead.")] 
    double Meth2(int input); 
    float Meth22(int input); 
} 
+0

ありがとう - 私は質問の最後にメモを追加しました。つまり、私はIOldインターフェイスを続行していません。 – Jeb

関連する問題