インターフェイスがあるとしましょうIFoo
:
public interface IFoo {
void Bar(string s);
int Quux(object o);
}
APIのバージョン2では、Glarg
このインターフェイスにメソッドを追加する必要があります。既存のAPIユーザーを破壊せず、後方互換性を維持せずに、どのように行いますか?これは主に.NETを対象としていますが、他のフレームワークと言語にも適用できます。
インターフェイスがあるとしましょうIFoo
:
public interface IFoo {
void Bar(string s);
int Quux(object o);
}
APIのバージョン2では、Glarg
このインターフェイスにメソッドを追加する必要があります。既存のAPIユーザーを破壊せず、後方互換性を維持せずに、どのように行いますか?これは主に.NETを対象としていますが、他のフレームワークと言語にも適用できます。
回答:
APIのバージョン2では、
Glarg
このインターフェイスにメソッドを追加する必要があります。
どうして?
APIで使用するために定義されたインターフェイスには、2つのまったく異なる役割があります。
今のために与えられたバージョンのAPIの、同じインターフェイスは両方として作用することができます。それでも、将来のバージョンでは、これを切り離すことができます。
「もっと返す」、つまりAPIから「より豊富な」オブジェクトを抽象化する必要があります。ここでは、2つの選択肢があります。
可能であれば前のインターフェイスから派生した新しいインターフェイスを定義します。そのような派生が不可能な場合は、新しいインターフェイスのインスタンスを照会するか、構成を使用する別のメソッドを作成します。
interface MyNewInterface extends MyOldInterface {
FancyNewInterface getFancyShit();
}
APIに新しいメソッドを追加するには、既存のAPIに副作用が生じないようにする必要があります。最も重要なことは、新しいAPIが存在しないかのように古いAPIを使い続ける人は、その影響を受けないことです。古いAPIを使用しても、新しいAPIに予期しない副作用が生じることはありません。
APIの既存のメソッドのいずれかが新しいものに置き換えられる場合は、すぐに削除しないでください。それらを非推奨としてマークし、代わりに何を使用すべきかについて説明してください。これにより、コードのユーザーに、警告なしにコードを壊すのではなく、将来のバージョンでサポートされなくなる可能性があることを警告します。
新しいAPIと古いAPIに互換性がなく、望ましくない副作用がなければ共存できない場合は、それらを分離し、新しいAPIを採用する場合は古いAPIを完全に廃止する必要があることを文書化します。常に両方を使用しようとする人がいて、それが機能しない場合はイライラするため、これはあまり望ましくありません。
.NETについて具体的に尋ねたので、次の例にリンクされている.NETの非推奨に関するこの記事を読むことをお勧めしますObsoleteAttribute
。
using System;
public sealed class App {
static void Main() {
// The line below causes the compiler to issue a warning:
// 'App.SomeDeprecatedMethod()' is obsolete: 'Do not call this method.'
SomeDeprecatedMethod();
}
// The method below is marked with the ObsoleteAttribute.
// Any code that attempts to call this method will get a warning.
[Obsolete("Do not call this method.")]
private static void SomeDeprecatedMethod() { }
}
パブリックインターフェイスの変更には破損が伴います。一般的な戦略は、これらをメジャーバージョンとフリーズ期間後にのみ行うことです(気まぐれでは発生しません)。新しいインターフェイスに追加を追加する場合は、クライアントを中断せずに逃げることができます(そして、実装は同じクラスで両方を提供できます)。それは理想的ではありません。それをやり続けると混乱が生じます。
ただし、他の種類の変更(メソッドの削除、署名の変更)では、スタックします。
インターフェイスはコントラクトであるため、バージョン管理を行うべきではありません。サッカー選手が新しい契約を取得するとどうなりますか?古いものはまだ有効ですか?いいえ。インターフェイスを変更すると、契約が変更され、以前の契約(インターフェイス)は無効になります。
IFoo2戦略を使用することもできますが、次のような場合に最終的には面倒になります。
うん
APIは異なります。使用するコードのライブラリを提供します。来月、更新されたライブラリを提供します。別のポスターが言ったように、私がすでに使用しているものを壊さないで、新しい機能/メソッドを追加してください。
何かをバージョン管理する場合は、インターフェイスの代わりに抽象クラスを使用します。