Wir benutzen eine Bibliothek, die von jemand anderem zur Verfügung gestellt wurde. Aufgrund von Änderungen in dieser Bibliothek hat unser Projekt in letzter Zeit 500 Fehler. Bei der Migration in die neue Bibliothek haben wir festgestellt, dass nur 15 APIs fehlschlagen und 500 Fehler sich wiederholen (mehrfaches Auftreten dieser 15 Fehler, da die gleichen Aufrufe so oft verwendet werden).
Also habe ich für die Migration vorgeschlagen, eine weitere interne statische Wrapper-Klasse zu erstellen, die diese Bibliotheks-API-Aufrufe umschließt. Denn wenn sich die Bibliothek wieder ändern würde, hätten wir weniger Code zu ändern, und der Code wird in Zukunft leichter zu pflegen sein. Und indem wir Aufrufe umhüllen, vermeiden wir menschliche Fehler (oder unbeabsichtigte (überladene) API-Verwendungen).
Aber einige Leute hier, sehen nicht den Punkt in einer anderen Wrapper-Klasse, die sie fühlen, ist total unnötig. Ihr einziger Argumentationspunkt ist, dass die meisten API-Änderungen nur aus einem Liner bestehen und wir sie daher immer mit STRG + H (Suchen und Ersetzen) ändern können. Und sie sagen auch, dass diese zusätzliche Abstraktion, die ich vorschlage, die Lesbarkeit wegnimmt (weil sie den eigentlichen API-Aufruf hinter einem anderen Methodennamen (obwohl sinnvoll)) für den Coder / Leser verbirgt.
Was ist der beste Ansatz hier? Verstehe ich meine Vorschläge falsch?
Es ist eine relativ übliche Vorgehensweise, instabile APIs und Bibliotheken mit benutzerdefinierten Wrappern zu verpacken. Eine allgemeine Verwendung besteht beispielsweise darin, Ausnahmen dieser Bibliothek in Ihre Nomenklatur von Ausnahmen zu übersetzen.
Allgemeiner sind diese Wrapper als Adapter bekannt, obwohl Adapter (IMHO) mehr dafür vorgesehen sind, Funktionalität bereitzustellen, die von einer Seite benötigt wird, während die exakte "Sprache" der anderen Seite versteckt wird, nicht weil die andere Seite instabil ist.
Sie haben den Einsatz von Statik erwähnt - ich bin generell kein großer Fan davon. IMHO ist es manchmal besser, eine Schnittstelle zu haben, die die Funktionalität darstellt, die Sie brauchen, und dann Subtypen dieser Schnittstelle zu haben, wenn einer dieser Subtypen die Third-Party-Bibliothek verwendet. Der Vorteil davon ist, dass Sie eines Tages zu einem anderen Anbieter wechseln können, ohne jeden Anruf in Ihrem System zu ändern.
Wie auch immer, Sie sind im Allgemeinen auf der richtigen Spur. Wer denkt, dass CTRL-H ein gültiges Refactoring-Tool ist, der fragt nach Ärger. Verwenden sie zumindest Getter und Setter (Wo zutreffend) in ihrem Code?
Auch der Lesbarkeitsteil ist mir unklar. Ein Adapter mit einem lesbaren Namen ist genauso gut wie eine ursprüngliche API mit einem lesbaren Namen.
Dies ist eigentlich bekannt als das Adapter -Muster, und es wurde speziell mit Ihrem genauen Problem erstellt ....
Adapter wird speziell dazu verwendet NOT Funktionalität hinzuzufügen, nur um eine Schnittstelle einer API an eine Schnittstelle anzupassen, die vom Aufrufer erwartet wird. Die Schnittstellen sind nur ein praktisches OO-Werkzeug, um die Adapterfunktion in einer konsistenten und managablen Weise zu implementieren, das Muster selbst beschreibt im Grunde, wie man ein Problem löst.
Wenn sich eine API ändert, ist ein Wrapper die einzige Möglichkeit, sich selbst zu schützen. Wenn Sie sich für eine API entschieden haben, die sich ändert, haben Sie große Risiken für Ihr Projekt. Indem Sie diese Risiken mit einem Wrapper mildern, können Sie sich auch selbst schützen, wenn Sie zu einer anderen Bibliothek wechseln möchten.
Um den Wrapper zu implementieren, müssen Sie den Wrapper erstellen und suchen und ersetzen.
Wie auch immer, Sie müssen immer noch alle Ihre Anrufe wegen der anfänglichen API-Änderung anfassen, also sehe ich nicht, dass die kleine Extra-Investition ein Problem ist.
Schwer zu sagen, ohne Ihren Code zu kennen, aber ich fühle mich wie eine Fassade / Adapter ist eine gute Möglichkeit, API-Anrufe von Ihrem eigenen Code zu trennen. Ich würde nicht so weit gehen zu sagen, dass es notwendig ist, aber es ist klarer imho.
Es hängt davon ab, was die API tut und ob das Hinzufügen einer anderen Ebene wirklich eine Isolierung / Einkapselung hinzufügt oder ob es lediglich eine weitere Indirektionsebene hinzufügt. Wenn eine Änderung in der API eine Änderung der öffentlichen Schnittstelle Ihres Wrappers erforderlich macht, wird es nur in die Quere kommen.
Eine Wrapper-Schicht eignet sich am besten, wenn Sie die Funktionalität auf einer Abstraktionsebene bereitstellen können, die für Ihre Anwendung sinnvoll ist, indem Sie die nicht benötigte API-Flexibilität verbergen und standardisieren, wie Sie auf die benötigte Funktionalität zugreifen. Dies kann auch die Verwendung von Funktions- und Parameternamen umfassen, die spezifischer für Ihre Problemdomäne sind. Dadurch kann die konzeptionelle Schwierigkeit beim Verständnis der Integration der API in Ihre Anwendung verringert werden.
Tags und Links oop