Die meisten Projekte, an denen ich beteiligt bin, verwenden mehrere Open-Source-Komponenten. Ist es grundsätzlich eine gute Idee, immer zu vermeiden, dass alle Komponenten des Codes an die Bibliotheken von Drittanbietern gebunden werden, und stattdessen einen Kapselungswrapper zu verwenden, um den Schmerz der Veränderung zu vermeiden?
Zum Beispiel verwenden die meisten unserer PHP-Projekte log4php direkt als Logging-Framework, dh sie instanziieren über \ Logger :: getLogger (), sie verwenden -> info () oder -> warn () -Methoden usw. In Zukunft Möglicherweise wird jedoch ein hypothetisches Protokollierungsframework angezeigt, das in gewisser Weise besser ist. So wie es aussieht, müssten alle Projekte, die eng mit den Signaturen der log4php-Methode gekoppelt sind, an Dutzenden Stellen geändert werden, um den neuen Signaturen zu entsprechen. Dies hätte natürlich weitreichende Auswirkungen auf die Codebasis, und jede Änderung ist ein potenzielles Problem.
Um neue Codebasen aus dieser Art von Szenario zukunftssicher zu machen, wird häufig eine Wrapper-Klasse in Betracht gezogen (und manchmal implementiert), um die Protokollierungsfunktionalität zu kapseln und die zukünftige Funktionsweise der Protokollierung mit minimalen Änderungen zu vereinfachen, obwohl dies nicht kinderleicht ist ; Der Code ruft den Wrapper auf, der Wrapper leitet den Aufruf an das Protokollierungsframework du jour weiter .
In Anbetracht der Tatsache, dass es kompliziertere Beispiele für andere Bibliotheken gibt, bin ich überentwickelt oder ist dies in den meisten Fällen eine kluge Vorsichtsmaßnahme?
BEARBEITEN: Weitere Überlegungen - für die Verwendung von Abhängigkeitsinjektion und Test-Double müssen die meisten APIs sowieso abstrahiert werden ("Ich möchte überprüfen, ob mein Code ausgeführt wird und seinen Status aktualisiert, aber keinen Protokollkommentar schreiben / auf eine echte Datenbank zugreifen"). Ist das nicht eine Entscheidung?
quelle
Antworten:
Wenn Sie nur eine kleine Teilmenge der API eines Drittanbieters verwenden, ist es sinnvoll, einen Wrapper zu schreiben. Dies hilft bei der Kapselung und beim Verbergen von Informationen und stellt sicher, dass Sie Ihrem eigenen Code keine möglicherweise große API aussetzen. Dies kann auch dazu beitragen, sicherzustellen, dass alle Funktionen, die Sie nicht verwenden möchten, "ausgeblendet" sind.
Ein weiterer guter Grund für einen Wrapper ist, wenn Sie damit rechnen , die Bibliothek eines Drittanbieters zu ändern. Wenn dies eine Infrastruktur ist, von der Sie wissen, dass Sie sie nicht ändern werden, schreiben Sie keinen Wrapper dafür.
quelle
Wie würden Sie den Wrapper schreiben, ohne zu wissen, welche großartigen neuen Funktionen dieser angeblich in Zukunft verbesserte Logger haben wird? Die logischste Wahl ist, dass Ihr Wrapper eine Art Logger-Klasse instanziiert und über Methoden wie
->info()
oder verfügt->warn()
. Mit anderen Worten, im Wesentlichen identisch mit Ihrer aktuellen API.Anstatt zukunftssicheren Code, den ich möglicherweise nie ändern muss oder der ohnehin ein unvermeidbares Umschreiben erfordert, ziehe ich es vor, Code "past-proof" zu machen. Das heißt, bei den seltenen Gelegenheiten , bei denen ich deutlich eine Komponente ändern, das ist , wenn ich einen Wrapper schreiben , um sie mit früherem Code kompatibel zu machen. Jeder neue Code verwendet jedoch die neue API, und ich überarbeite den alten Code, um ihn zu verwenden, wenn ich ohnehin eine Änderung in derselben Datei vornehme oder wenn es der Zeitplan zulässt. Nach ein paar Monaten kann ich den Wrapper entfernen, und die Änderung war schrittweise und robust.
Anders ausgedrückt: Wrapper sind nur dann sinnvoll, wenn Sie bereits alle APIs kennen, die Sie zum Wrappen benötigen. Gute Beispiele sind, wenn Ihre Anwendung derzeit viele verschiedene Datenbanktreiber, Betriebssysteme oder PHP-Versionen unterstützen muss.
quelle
Indem Sie eine Bibliothek eines Drittanbieters einschließen, fügen Sie eine zusätzliche Abstraktionsebene hinzu. Dies hat einige Vorteile:
Ihre Codebasis wird flexibler für Änderungen
Wenn Sie die Bibliothek jemals durch eine andere ersetzen müssen, müssen Sie nur Ihre Implementierung in Ihrem Wrapper ändern - an einem Ort . Sie können die Implementierung des Wrappers ändern und müssen an nichts anderem etwas ändern, mit anderen Worten, Sie haben ein lose gekoppeltes System. Andernfalls müssten Sie Ihre gesamte Codebasis durchgehen und überall Änderungen vornehmen - was offensichtlich nicht das ist, was Sie wollen.
Sie können die API des Wrappers unabhängig von der API der Bibliothek definieren
Verschiedene Bibliotheken können sehr unterschiedliche APIs haben, und gleichzeitig ist keine davon genau das, was Sie benötigen. Was ist, wenn in einer Bibliothek bei jedem Aufruf ein Token übergeben werden muss? Sie können das Token in Ihrer App überall dort weitergeben, wo Sie die Bibliothek verwenden möchten, oder Sie können es an einem zentraleren Ort speichern, aber auf jeden Fall benötigen Sie das Token. Mit Ihrer Wrapper-Klasse ist das wieder ganz einfach: Sie können das Token einfach in Ihrer Wrapper-Klasse belassen, es niemals einer Komponente in Ihrer App aussetzen und die Notwendigkeit dafür vollständig ausschließen. Ein großer Vorteil, wenn Sie jemals eine Bibliothek verwendet haben, die kein gutes API-Design hervorhebt.
Unit-Tests sind viel einfacher
Unit-Tests sollten nur eines testen. Wenn Sie eine Klasse einem Komponententest unterziehen möchten, müssen Sie sich über ihre Abhängigkeiten lustig machen. Dies wird noch wichtiger, wenn diese Klasse Netzwerkanrufe durchführt oder auf eine andere Ressource außerhalb Ihrer Software zugreift. Indem Sie die Bibliothek eines Drittanbieters einbinden, können Sie diese Aufrufe einfach verspotten und Testdaten oder was auch immer für diesen Komponententest erforderlich ist, zurückgeben. Wenn Sie nicht über eine solche Abstraktionsebene verfügen, wird dies sehr viel schwieriger - und die meiste Zeit führt dies zu viel hässlichem Code.
Sie erstellen ein lose gekoppeltes System
Änderungen an Ihrem Wrapper haben keine Auswirkungen auf andere Teile Ihrer Software - zumindest solange Sie das Verhalten Ihres Wrappers nicht ändern. Durch die Einführung einer Abstraktionsebene wie dieser Wrapper können Sie die Aufrufe der Bibliothek vereinfachen und die Abhängigkeit Ihrer App von dieser Bibliothek fast vollständig entfernen. Ihre Software verwendet nur den Wrapper und es macht keinen Unterschied, wie der Wrapper implementiert ist oder was er tut.
Praktisches Beispiel
Lass uns ehrlich sein. Die Leute können stundenlang über die Vor- und Nachteile von so etwas streiten - deshalb zeige ich Ihnen lieber nur ein Beispiel.
Angenommen, Sie haben eine Art Android-App und müssen Bilder herunterladen. Es gibt eine Reihe von Bibliotheken, die das Laden und Zwischenspeichern von Bildern zum Kinderspiel machen, zum Beispiel Picasso oder den Universal Image Loader .
Wir können jetzt eine Schnittstelle definieren, die wir verwenden, um die Bibliothek zu verpacken, die wir letztendlich verwenden:
Dies ist die Benutzeroberfläche, die wir jetzt in der gesamten App verwenden können, wenn wir ein Bild laden müssen. Wir können eine Implementierung dieser Schnittstelle erstellen und mithilfe der Abhängigkeitsinjektion eine Instanz dieser Implementierung überall dort einfügen, wo wir die verwenden
ImageService
.Nehmen wir an, wir entscheiden uns zunächst für Picasso. Wir können jetzt eine Implementierung schreiben, für
ImageService
die Picasso intern verwendet wird:Ziemlich direkt, wenn du mich fragst. Wrapper um Bibliotheken müssen nicht kompliziert sein, um nützlich zu sein. Die Schnittstelle und die Implementierung haben weniger als 25 kombinierte Codezeilen, so dass es kaum Aufwand gab, dies zu erstellen, aber wir gewinnen bereits etwas, indem wir dies tun. Siehe das
Context
Feld in der Implementierung? Das Abhängigkeitsinjektionsframework Ihrer Wahl wird sich bereits darum kümmern, diese Abhängigkeit zu injizieren, bevor wir unsere verwendenImageService
. Ihre App muss sich jetzt nicht mehr darum kümmern, wie die Bilder heruntergeladen werden und welche Abhängigkeiten diese Bibliothek möglicherweise hat. Alles, was Ihre App sieht, ist einImageService
und wenn sie ein Bild benötigt, ruft sie esload()
mit einer URL auf - einfach und unkompliziert.Der eigentliche Vorteil ergibt sich jedoch, wenn wir anfangen, Dinge zu ändern. Stellen Sie sich vor, wir müssen Picasso jetzt durch Universal Image Loader ersetzen, da Picasso einige Funktionen, die wir momentan unbedingt benötigen, nicht unterstützt. Müssen wir jetzt unsere Codebasis durchkämmen und mühsam alle Aufrufe von Picasso ersetzen und uns dann mit Dutzenden von Kompilierungsfehlern befassen, weil wir einige Picasso-Aufrufe vergessen haben? Nein. Wir müssen lediglich eine neue Implementierung von erstellen
ImageService
und unserem Abhängigkeitsinjektionsframework mitteilen, dass diese Implementierung von nun an verwendet werden soll:Wie Sie sehen, kann die Implementierung sehr unterschiedlich sein, aber es spielt keine Rolle. Wir mussten an keiner anderen Stelle in unserer App eine einzige Codezeile ändern. Wir verwenden eine völlig andere Bibliothek, die möglicherweise völlig andere Funktionen aufweist oder sehr unterschiedlich verwendet wird, aber unsere App kümmert sich einfach nicht darum. Wie zuvor sieht der Rest unserer App nur das
ImageService
Interface mit seinerload()
Methode und diese Methode ist jedoch nicht mehr von Bedeutung.Zumindest für mich klingt das alles schon ganz nett, aber warte! Es gibt noch mehr. Stellen Sie sich vor, Sie schreiben Komponententests für eine Klasse, an der Sie arbeiten, und diese Klasse verwendet die
ImageService
. Natürlich können Sie nicht zulassen, dass Ihre Komponententests Netzwerkanrufe an eine Ressource auf einem anderen Server senden, aber da Sie jetzt die verwendenImageService
, können Sieload()
eineBitmap
für die Komponententests verwendete statische Aufladung einfach zurückgeben lassen , indem Sie eine verspottete Anweisung implementierenImageService
:Zusammenfassend lässt sich festhalten, dass Ihre Codebasis durch das Einschließen von Bibliotheken von Drittanbietern flexibler für Änderungen wird, insgesamt einfacher und einfacher zu testen ist und Sie die Kopplung verschiedener Komponenten in Ihrer Software verringern - alles Dinge, die immer wichtiger werden, je länger Sie eine Software warten.
quelle
Ich denke, dass es eine sehr verschwenderische Verletzung von YAGNI ist, heute Bibliotheken von Drittanbietern einzupacken, falls morgen etwas Besseres herauskommt. Wenn Sie wiederholt Code von Drittanbietern in einer für Ihre Anwendung spezifischen Weise aufrufen, werden Sie diese Aufrufe in eine Wrapping-Klasse umstrukturieren (sollten), um die Wiederholung zu vermeiden. Andernfalls verwenden Sie die Bibliotheks-API vollständig und jeder Wrapper würde genau wie die Bibliothek selbst aussehen.
Angenommen, jetzt wird eine neue Bibliothek mit überragender Leistung oder was auch immer angezeigt. Im ersten Fall schreiben Sie einfach den Wrapper für die neue API neu. Kein Problem.
Im zweiten Fall erstellen Sie einen Wrapper, der die alte Schnittstelle an das Laufwerk der neuen Bibliothek anpasst. Ein bisschen mehr Arbeit, aber kein Problem, und nicht mehr Arbeit, als Sie getan hätten, wenn Sie den Wrapper früher geschrieben hätten.
quelle
Der Hauptgrund für das Schreiben eines Wrappers um eine Drittanbieter-Bibliothek besteht darin, dass Sie diese Drittanbieter-Bibliothek austauschen können, ohne den Code zu ändern, der sie verwendet. Sie können es nicht vermeiden, an etwas zu koppeln. Daher wird argumentiert, dass es besser ist, eine von Ihnen geschriebene API zu koppeln.
Ob sich die Mühe lohnt, ist eine andere Geschichte. Diese Debatte wird wahrscheinlich noch lange dauern.
Bei kleinen Projekten, bei denen die Wahrscheinlichkeit, dass eine solche Änderung erforderlich ist, gering ist, ist dies wahrscheinlich unnötiger Aufwand. Bei größeren Projekten überwiegt diese Flexibilität möglicherweise den zusätzlichen Aufwand für das Einpacken der Bibliothek. Es ist jedoch schwierig, vorher zu wissen, ob dies der Fall ist.
Eine andere Sichtweise ist das Grundprinzip der Abstraktion dessen, was sich wahrscheinlich ändern wird. Wenn die Bibliothek eines Drittanbieters gut etabliert ist und wahrscheinlich nicht geändert wird, ist es möglicherweise in Ordnung, sie nicht zu verpacken. Wenn die Bibliothek eines Drittanbieters jedoch relativ neu ist, besteht eine größere Wahrscheinlichkeit, dass sie ersetzt werden muss. Die Entwicklung etablierter Bibliotheken wurde jedoch schon oft aufgegeben. Diese Frage ist also nicht einfach zu beantworten.
quelle
Zusätzlich zu dem, was @Oded bereits gesagt hat, möchte ich diese Antwort nur für den speziellen Zweck der Protokollierung hinzufügen.
Ich habe immer eine Schnittstelle für die Protokollierung, aber ich musste noch nie ein
log4foo
Framework ersetzen .Es dauert nur eine halbe Stunde, um die Schnittstelle bereitzustellen und den Wrapper zu schreiben, sodass Sie vermutlich nicht zu viel Zeit verschwenden, wenn sich herausstellt, dass dies nicht erforderlich ist.
Es ist ein Sonderfall von YAGNI. Obwohl ich es nicht brauche, dauert es nicht lange und ich fühle mich sicherer damit. Wenn der Tag des Austauschs des Loggers wirklich kommt, bin ich froh, dass ich eine halbe Stunde investiert habe, weil ich dadurch mehr als einen Tag Zeit für den Austausch von Anrufen in einem realen Projekt habe. Und ich habe noch nie einen Komponententest für die Protokollierung geschrieben oder gesehen (abgesehen von Tests für die Protokollierungsimplementierung selbst). Erwarten Sie also Fehler ohne den Wrapper.
quelle
Ich beschäftige mich mit genau diesem Problem in einem Projekt, an dem ich gerade arbeite. In meinem Fall ist die Bibliothek jedoch für Grafiken vorgesehen, und daher kann ich ihre Verwendung auf eine kleine Anzahl von Klassen beschränken, die sich mit Grafiken befassen, anstatt sie über das gesamte Projekt zu verteilen. So ist es ziemlich einfach, APIs später zu wechseln, wenn ich muss; Im Falle eines Loggers wird die Sache viel komplizierter.
Daher würde ich sagen, dass die Entscheidung viel damit zu tun hat, was genau die Bibliothek von Drittanbietern tut und wie viel Schmerz damit verbunden wäre, sie zu ändern. Wenn es einfach wäre, alle API-Aufrufe zu ändern, lohnt es sich wahrscheinlich nicht. Wenn es jedoch sehr schwierig wäre, die Bibliothek später zu ändern, würde ich sie wahrscheinlich jetzt einpacken.
Darüber hinaus haben andere Antworten die Hauptfrage sehr gut abgedeckt, sodass ich mich nur auf die letzte Ergänzung konzentrieren möchte, die sich mit Abhängigkeitsinjektionen und Scheinobjekten befasst. Es hängt natürlich davon ab, wie genau Ihr Protokollierungsframework funktioniert, aber in den meisten Fällen ist kein Wrapper erforderlich (obwohl es wahrscheinlich von einem profitieren wird). Stellen Sie einfach die API für Ihr Mock-Objekt genau so ein wie die Bibliothek eines Drittanbieters, und Sie können das Mock-Objekt zum Testen problemlos austauschen.
Der Hauptfaktor hierbei ist, ob die Bibliothek eines Drittanbieters sogar durch Abhängigkeitsinjektion (oder einen Dienstlokalisierer oder ein solches lose gekoppeltes Muster) implementiert wird oder nicht. Wenn auf die Bibliotheksfunktionen über ein Singleton oder statische Methoden oder etwas anderes zugegriffen wird, müssen Sie dies in ein Objekt einschließen, mit dem Sie in Abhängigkeitsinjektion arbeiten können.
quelle
Ich bin stark im Wrapping-Camp und nicht in der Lage, die Drittanbieter-Bibliothek mit der höchsten Priorität zu ersetzen (obwohl das ein Bonus ist). Mein Hauptgrund, der das Wickeln bevorzugt, ist einfach
Und dies manifestiert sich in der Regel in Form einer Schiffsladung von Code-Duplikaten, z. B.
QButton
wenn Entwickler 8 Codezeilen schreiben, um einen Code so zu erstellen und zu formatieren, wie er für die Anwendung aussehen sollte, und nur, wenn der Designer nicht nur das Aussehen haben möchte aber auch die Funktionalität der Schaltflächen, die sich für die gesamte Software vollständig ändern, was dazu führt, dass Tausende von Codezeilen zurückgeschrieben und neu geschrieben werden müssen, oder dass die Modernisierung einer Rendering-Pipeline ein episches Umschreiben erfordert, da die Codebasis mit Ad-hoc-Fixes auf niedriger Ebene bestreut ist. Pipeline-OpenGL-Code wird überall verwendet, anstatt ein Echtzeit-Renderer-Design zu zentralisieren und die Verwendung von OGL für dessen Implementierung strikt zu überlassen.Diese Designs sind nicht auf unsere spezifischen Designanforderungen zugeschnitten. Sie bieten in der Regel einen großen Teil dessen, was tatsächlich benötigt wird (und was nicht Teil eines Designs ist, ist genauso wichtig, wenn nicht mehr als das, was ist), und ihre Schnittstellen sind nicht speziell darauf ausgelegt, unsere Anforderungen auf hohem Niveau zu erfüllen thought = one request "Art und Weise, die uns jegliche zentrale Designkontrolle entzieht, wenn wir sie direkt verwenden. Wenn die Entwickler am Ende viel weniger Code schreiben, als sie benötigen, um auszudrücken, was sie brauchen, können sie ihn manchmal selbst ad-hoc verpacken, so dass Sie am Ende Dutzende von hastig geschriebenen und groben Codes haben. entworfene und dokumentierte Wrapper statt eines gut entworfenen, gut dokumentierten.
Natürlich würde ich Bibliotheken, bei denen es sich bei den Wrappern fast um Eins-zu-Eins-Übersetzungen der APIs von Drittanbietern handelt, strenge Ausnahmen zuweisen. In diesem Fall ist möglicherweise kein übergeordnetes Design zu suchen, das die geschäftlichen und gestalterischen Anforderungen direkter zum Ausdruck bringt (dies könnte der Fall sein, wenn etwas eher einer "Utility" -Bibliothek ähnelt). Aber wenn es ein viel maßgeschneiderteres Design gibt, das unsere Bedürfnisse viel direkter zum Ausdruck bringt, dann bin ich stark im Wrapping Camp, genauso wie ich es stark befürworte, eine übergeordnete Funktion zu verwenden und sie über inline Assembler-Code wiederzuverwenden überall.
Seltsamerweise habe ich mich mit Entwicklern auf eine Weise gestritten, bei der sie so misstrauisch und pessimistisch wirkten, wenn es darum ging, beispielsweise eine Funktion zum Erstellen und Zurückgeben von Schaltflächen zu entwerfen, dass sie lieber 8 Zeilen Code auf niedrigerer Ebene schreiben würden, der sich auf Mikroskopie konzentriert Details der Schaltflächenerstellung (die in Zukunft wiederholt geändert werden musste) über das Entwerfen und Verwenden dieser Funktion. Ich sehe nicht einmal den Grund, warum wir überhaupt versuchen, etwas zu entwerfen, wenn wir uns nicht darauf verlassen können, dass wir diese Art von Umhüllungen auf vernünftige Weise entwerfen.
Anders ausgedrückt, ich betrachte Bibliotheken von Drittanbietern als Möglichkeiten, um möglicherweise enorme Zeit bei der Implementierung zu sparen, und nicht als Ersatz für das Entwerfen von Systemen.
quelle
Meine Idee zu Bibliotheken von Drittanbietern:
In letzter Zeit gab es in der iOS-Community einige Diskussionen über Vor- und Nachteile (OK, meistens Nachteile) der Verwendung von Abhängigkeiten von Drittanbietern. Viele Argumente waren eher allgemein gehalten: Alle Bibliotheken von Drittanbietern in einem Korb zusammenfassen. Wie bei den meisten Dingen ist es jedoch nicht so einfach. Konzentrieren wir uns also auf einen einzelnen Fall
Sollten wir die Verwendung von UI-Bibliotheken von Drittanbietern vermeiden?
Gründe, Bibliotheken von Drittanbietern in Betracht zu ziehen:
Es gibt anscheinend zwei Hauptgründe, warum Entwickler die Verwendung einer Drittanbieter-Bibliothek in Betracht ziehen:
Die meisten UI-Bibliotheken ( nicht alle! ) Fallen in die zweite Kategorie. Dieses Zeug ist keine Raketenwissenschaft, aber es braucht Zeit, um es richtig zu bauen.
Es gibt zwei Arten von Steuerelementen / Ansichten:
UICollectionView
ausUIKit
.UIPickerView
. Die meisten Bibliotheken von Drittanbietern fallen in die zweite Kategorie. Außerdem werden sie häufig aus einer vorhandenen Codebasis extrahiert, für die sie optimiert wurden.Unbekannte frühe Annahmen
Viele Entwickler führen Codeüberprüfungen ihres internen Codes durch, halten jedoch die Qualität des Quellcodes von Drittanbietern möglicherweise für selbstverständlich. Es lohnt sich, ein bisschen Zeit damit zu verbringen, nur den Code einer Bibliothek zu durchsuchen. Es kann sein, dass Sie überrascht sind, einige rote Flaggen zu sehen, z. B. wenn das Swizzeln dort eingesetzt wird, wo es nicht benötigt wird.
Du kannst es nicht verstecken
Aufgrund des Designs von UIKit können Sie die UI-Bibliothek eines Drittanbieters wahrscheinlich nicht ausblenden, z. B. hinter einem Adapter. Eine Bibliothek wird mit Ihrem UI-Code verflochten und wird de facto zu Ihrem Projekt.
Zukünftige Zeitkosten
UIKit ändert sich mit jeder iOS-Version. Die Dinge werden brechen. Ihre Abhängigkeit von Drittanbietern ist nicht so wartungsfrei, wie Sie es vielleicht erwarten.
Fazit :
Nach meiner persönlichen Erfahrung läuft die Verwendung von UI-Code von Drittanbietern meist darauf hinaus, die geringere Flexibilität gegen einen gewissen Zeitgewinn auszutauschen.
Wir verwenden vorgefertigten Code, um unsere aktuelle Version schneller zu versenden. Früher oder später stoßen wir jedoch an die Grenzen der Bibliothek und stehen vor einer schwierigen Entscheidung: Was tun?
quelle
Die direkte Nutzung der Bibliothek ist für das Entwicklerteam angenehmer. Wenn sich ein neuer Entwickler anmeldet, ist er möglicherweise mit allen verwendeten Frameworks vollständig vertraut, kann jedoch keinen produktiven Beitrag leisten, bevor er die von ihm selbst entwickelte API erlernt hat. Wenn ein jüngerer Entwickler versucht, in Ihrer Gruppe voranzukommen, muss er lernen, dass Ihre spezifische API nirgendwo anders vorhanden ist, anstatt sich eine nützlichere allgemeine Kompetenz anzueignen. Wenn jemand nützliche Funktionen oder Möglichkeiten der ursprünglichen API kennt, ist er möglicherweise nicht in der Lage, über die Ebene zu gelangen, die von jemandem geschrieben wurde, der sich dessen nicht bewusst war. Wenn jemand auf der Suche nach einem Job eine Programmieraufgabe erhält, kann er möglicherweise nicht die grundlegenden Dinge demonstrieren, die er oft verwendet hat, nur weil er all diese Male über Ihren Wrapper auf die erforderlichen Funktionen zugegriffen hat.
Ich denke, dass diese Probleme wichtiger sind als die Möglichkeit, später eine komplett andere Bibliothek zu verwenden. Der einzige Fall, in dem ich einen Wrapper verwenden würde, ist, wenn die Migration auf eine andere Implementierung definitiv geplant ist oder die umschlossene API nicht ausreichend eingefroren ist und sich ständig ändert.
quelle