5

下位互換性を損なうことなく、コード ライブラリを段階的に更新するクリーンな方法を探しています。これは、新しいメンバーをクラスに追加したり、既存のメンバーを変更して追加機能を提供したりすることを意味します。場合によっては、既存のコードを壊すような方法でメンバーを変更する必要がある場合があります (メソッドの名前を変更したり、戻り値の型を変更したりするなど)。

私が現在これをセットアップする方法は、そのクラスの以前の「バージョン」を拡張する新しいクラスを作成することによる継承とポリモーフィズムによるものです。

クラス図

これが機能する方法は、プロパティの実際の値に基づいてStatusResult(たとえば)の適切なバージョンを作成し、それを のインスタンスとして返すことです。StatusResultVersion3ProtocolVersionCommandResult

.NET にはクラスのバージョン管理の概念がないように思われるため、クラス名の末尾にバージョン番号を追加する独自の方法を考案する必要がありました。これは間違いなくあなたをうんざりさせます。ダイアグラムを拡大した後、自分が目を引っ掻いているのが容易に想像できます。しかし、それは機能します。コードを壊す変更を導入することなく、新しいメンバーを追加して既存のメンバーをオーバーライドできます。

クラスをバージョン管理するためのより良い方法はありますか?

4

4 に答える 4

1

インターフェースの問題は、いったん公開されると、ほとんどが固定されていることです。Anders Hejlsburg の引用:

... インターフェイスにメソッドを追加するようなものです。インターフェイスを公開した後は、すべての実用的な目的で不変になります。これは、インターフェイスの実装には、次のバージョンで追加するメソッドが含まれている可能性があるためです。そのため、代わりに新しいインターフェイスを作成する必要があります。

したがって、インターフェイスを更新するだけではいけません。完全に新しいインターフェイスを作成する必要があります。もちろん、単一のクラスで両方のインターフェースを実装することもできるので、時間の経過とともにコードが複数のクラスに分散される (たとえば) ポリモーフィック クラスと比較して、メンテナンスの労力はかなり少なくなります。

複数のインターフェイスを使用すると、クラスにはない方法でメソッドを削除することもできます (確かに、それらを非推奨にすることはできますが、数回の反復後に非常にノイズの多い intellisense が発生する可能性があります)。

私は個人的に、各アセンブリ バージョンに完全にスタンドアロンのインターフェイス バージョンを用意することに傾倒しています。

つまり…

v 0.1.0.0

interface IExample
{
    String DoSomething();
}

v 0.2.0.0

interface IExample
{
    void DoSomethingElse();
}

舞台裏でそれらをどのように実装するかはあなた次第ですが、ほとんどの場合、同様の仕事をするわずかに異なるメソッドを持つ同じクラスになります (そうでなければ、なぜ同じインターフェースを使用するのでしょうか?)

古いコードはすべて参照する必要が0.1.x.xあり、新しいコードは を参照し0.2.x.xます。唯一の問題は、(たとえば) セキュリティ上の欠陥を見つけて、修正を以前のバージョンに移植する必要がある場合です。ここで、まともな VCS の出番です (個人的な好みは TFS ですが、SVN など、分岐/マージをサポートするものであれば何でもかまいません)。

ブランチからの修正をマージして0.2ブランチに戻し0.1、再コンパイルして (たとえば) を生成し0.1.1.0ます。

このようなプロセスに固執する限り:

これにより、以下が得られます。

  • 従来の乱雑さのないクリーンなコードベース
  • 何も問題がなければ、クライアントはコードを変更することなく最新バージョンを使用できます
  • クライアントが再コンパイルするまで、重大な変更がある新しいバージョンのアセンブリを使用できないようにします (そして、新しい機能を利用するためにコードを適切に更新することをお勧めします)。
  • 以前のバージョンのセキュリティ パッチをリリースできます
于 2013-07-21T09:14:59.387 に答える
1

既存のコードとアセンブリの更新を検討する場合、通常は次の 2 つのアプローチがあります。

  1. 回帰試験

    これは、互換性に影響を与えない変更を行うための優れたアプローチであり、単純に関数をオーバーロードして新しいパラメーターなどを提供できます。Visual Studio には、回帰テストを比較的簡単かつ自動化するための非常に高度な単体テスト機能がいくつかあります。

  2. アセンブリ バージョン

    一部のユーティリティの動作方法を書き直すなど、変更によって問題が発生し始める場合は、新しいアセンブリ バージョンを使用する必要があります。.NET は、アセンブリ バージョンの操作に非常に適しています。バージョン管理されたアセンブリを別のフォルダーに展開して、既存のコードが引き続き古いバージョンを参照できるようにし、新しいコードが新しいバージョンの機能を利用できるようにすることができます。

于 2013-05-25T17:02:03.467 に答える