Angenommen, Sie haben eine Schnittstelle IFoo
:
public interface IFoo {
void Bar(string s);
int Quux(object o);
}
In Version 2 Ihrer API müssen Sie Glarg
dieser Schnittstelle eine Methode hinzufügen . Wie können Sie dies tun, ohne Ihre vorhandenen API-Benutzer zu beschädigen und die Abwärtskompatibilität aufrechtzuerhalten? Dies richtet sich hauptsächlich an .NET, kann aber auch auf andere Frameworks und Sprachen angewendet werden.
versioning
interfaces
thecoop
quelle
quelle
Antworten:
Warum?
Die für die Verwendung mit einer API definierten Schnittstellen haben zwei völlig unterschiedliche Rollen:
Nun kann für eine bestimmte Version einer API dieselbe Schnittstelle als beide fungieren. In zukünftigen Versionen kann dies jedoch entkoppelt werden.
Sie möchten "mehr zurückgeben", dh die Abstraktion eines "reichhaltigeren" Objekts von Ihrer API. Hier haben Sie zwei Möglichkeiten:
Definieren Sie eine neue Schnittstelle, wenn möglich abgeleitet von der vorherigen. Wenn eine solche Ableitung nicht möglich ist, erstellen Sie separate Methoden, um Instanzen der neuen Schnittstelle abzufragen, oder verwenden Sie die Komposition:
quelle
DirectX fügte seinen Schnittstellen Versionsnummern hinzu. In Ihrem Fall wäre die Lösung so ähnlich
Die API verweist weiterhin auf IFoo und auf IFoo2 nur in Methoden usw., in denen IFoo2-Funktionalität erforderlich ist.
Die API-Implementierung sollte in vorhandenen (= Version 1) Methoden prüfen, ob ein IFoo-Parameterobjekt IFoo2 tatsächlich implementiert, wenn die Methodensemantik für IFoo2 unterschiedlich ist.
quelle
Das Hinzufügen einer neuen Methode (oder neuer Methoden) zu Ihrer API sollte so erfolgen, dass keine Nebenwirkungen auf die vorhandene API auftreten. Vor allem sollte jemand, der die alte API weiterhin verwendet, als ob die neue API nicht existiert, davon unberührt bleiben. Die Verwendung der alten API sollte auch keine unerwarteten Nebenwirkungen auf die neue API haben.
Wenn eine der vorhandenen Methoden in der API durch die neuen ersetzt wird, entfernen Sie sie nicht sofort. Markieren Sie sie als veraltet und erläutern Sie, was stattdessen verwendet werden soll. Das gibt Benutzern Ihres Codes die Warnung, dass zukünftige Versionen ihn möglicherweise nicht mehr unterstützen, anstatt ihren Code ohne Warnung zu brechen.
Wenn die neue und die alte API nicht kompatibel sind und nicht ohne unerwünschte Nebenwirkungen zusammenleben können, trennen Sie sie und dokumentieren Sie, dass die alte API vollständig zurückgezogen werden muss, wenn die neue API übernommen werden soll. Dies ist weniger wünschenswert, da es immer jemanden gibt, der versucht, beides zu verwenden, und der frustriert ist, wenn es nicht funktioniert.
Da Sie speziell nach .NET gefragt haben, möchten Sie möglicherweise diesen Artikel über die Veraltetheit in .NET lesen , der auf die
ObsoleteAttribute
(im folgenden Beispiel verwendete) verweist:quelle
Änderungen an der öffentlichen Schnittstelle sind mit Brüchen verbunden. Die übliche Strategie besteht darin, dies nur in Hauptversionen und nach einer Einfrierperiode zu tun (dies geschieht also nicht aus einer Laune heraus). Sie können davonkommen, ohne Ihre Clients zu beschädigen, wenn Sie Ihre Ergänzungen zu einer neuen Schnittstelle hinzufügen (und Ihre Implementierung kann beide in derselben Klasse bereitstellen). Das ist nicht ideal, und wenn du es weiter machst, wirst du ein Durcheinander haben.
Mit anderen Modifikationen (Entfernen von Methoden, Ändern von Signaturen) stecken Sie jedoch fest.
quelle
Ein Interface ist ein Vertrag, daher sollte es keine Versionierung haben. Was passiert, wenn ein Fußballspieler einen neuen Vertrag bekommt? Ist der alte noch gültig? Nein. Ändert man die Schnittstelle, ändert sich der Vertrag und der vorherige Vertrag (Schnittstelle) ist nicht mehr gültig.
Obwohl Sie die IFoo2-Strategie verwenden könnten, wird dies mit der Zeit unübersichtlich, wenn Sie:
Yuck.
Eine API ist anders. Ich gebe Bibliothek von Code zu verwenden. Nächsten Monat gebe ich Ihnen eine aktualisierte Bibliothek. Wie in einem anderen Poster bereits gesagt wurde, brechen Sie nicht das, was ich bereits benutze, sondern fügen Sie einfach neue Funktionen / Methoden hinzu.
Wenn Sie etwas versionieren möchten, verwenden Sie eine abtract-Klasse anstelle einer Schnittstelle.
quelle