Vorausgesetzt, Sie suchen nicht nach einem spöttischen Framework, da es allgegenwärtig und leicht zu finden ist , gibt es ein paar Dinge, die Sie im Vorfeld beachten sollten:
- Es gibt "nie" etwas, was Sie "immer" tun sollten.
Es ist nicht immer das Beste, eine Bibliothek eines Drittanbieters einzuschließen. Wenn Ihre Anwendung von einer Bibliothek abhängig ist oder buchstäblich aus einer oder zwei Kernbibliotheken besteht, verschwenden Sie keine Zeit damit, sie zusammenzufassen. Wenn sich die Bibliotheken ändern, muss sich Ihre Anwendung trotzdem ändern .
- Es ist in Ordnung, Integrationstests zu verwenden.
Dies gilt insbesondere für Grenzen, die stabil sind, für Ihre Anwendung von Bedeutung sind oder nicht einfach verspottet werden können. Wenn diese Bedingungen erfüllt sind, Wickel und spöttische werden kompliziert und langwierig werden. In diesem Fall würde ich beides vermeiden: nicht einwickeln und nicht verspotten; Schreiben Sie einfach Integrationstests. (Wenn automatisiertes Testen ein Ziel ist.)
- Tools und Frameworks können die logische Komplexität nicht beseitigen.
Grundsätzlich kann ein Werkzeug nur die Kesselplatte entlasten. Es gibt jedoch keinen automatisierbaren Algorithmus, um eine komplexe Schnittstelle zu erstellen und zu vereinfachen - geschweige denn, um die Schnittstelle X zu verwenden und an Ihre Bedürfnisse anzupassen. (Nur Sie kennen diesen Algorithmus!) Obwohl es zweifellos Tools gibt, die Thin Wrapper generieren können , würde ich vorschlagen, dass sie nicht bereits allgegenwärtig sind, da Sie am Ende immer noch nur intelligent und daher manuell codieren müssen. gegen die Schnittstelle, auch wenn es hinter einem Wrapper versteckt ist.
Es gibt jedoch Taktiken, die Sie in vielen Sprachen anwenden können, um nicht direkt auf eine Klasse zu verweisen. In einigen Fällen können Sie eine Schnittstelle oder einen Thin Wrapper "vortäuschen", die bzw. der nicht existiert. In C # würde ich zum Beispiel eine von zwei Routen gehen:
- Verwenden Sie eine Factory und implizite Typisierung .
Mit dieser kleinen Kombination können Sie den Aufwand vermeiden, eine komplexe Klasse vollständig zu verpacken:
// "factory"
class PdfDocumentFactory {
public static ExternalPDFLibraryDocument Build() {
return new ExternalPDFLibraryDocument();
}
}
// code that uses the factory.
class CoreBusinessEntity {
public void DoImportantThings() {
var doc = PdfDocumentFactory.Build();
// ... i have no idea what your lib does, so, I'm making stuff but.
// but, you can do whatever you want here without explicitly
// referring to the library's actual types.
doc.addHeader("Wee");
doc.getAllText().makeBiggerBy(4).makeBold().makeItalic();
return doc.exportBinaryStreamOrSomething();
}
}
Wenn Sie vermeiden können, diese Objekte als Mitglieder zu speichern, entweder durch einen "funktionaleren" Ansatz oder durch Speichern in einem Wörterbuch (oder was auch immer ), bietet dieser Ansatz den Vorteil einer Typprüfung zur Kompilierungszeit, ohne dass Ihre Kerngeschäftseinheiten dies genau wissen müssen Mit welcher Klasse arbeiten sie?
Alles, was erforderlich ist, ist, dass die von Ihrer Factory zurückgegebene Klasse zur Kompilierungszeit tatsächlich die Methoden enthält, die Ihr Geschäftsobjekt verwendet.
- Verwenden Sie die dynamische Eingabe .
Dies entspricht der Verwendung der impliziten Typisierung , ist jedoch mit einem anderen Kompromiss verbunden: Sie verlieren Überprüfungen des Kompilierungstyps und erhalten die Möglichkeit, externe Abhängigkeiten anonym als Klassenmitglieder hinzuzufügen und Abhängigkeiten einzufügen .
class CoreBusinessEntity {
dynamic Doc;
public void InjectDoc(dynamic Doc) {
Doc = doc;
}
public void DoImortantThings() {
Doc.addHeader("Wee");
Doc.getAllText().makeBiggerBy(4).makeBold().makeItalic();
return Doc.exportBinaryStreamOrSomething();
}
}
Bei beiden Taktiken müssen Sie, wenn es darum geht, sich zu verspotten ExternalPDFLibraryDocument
, wie ich bereits sagte, noch einiges an Arbeit leisten - aber es ist Arbeit, die Sie sowieso erledigen müssen . Und mit dieser Konstruktion haben Sie es vermieden, mühsam Hunderte von dünnen kleinen Wrapper-Klassen zu definieren. Sie haben die Bibliothek einfach benutzt, ohne sie direkt anzusehen - zum größten Teil.
Nach alledem gibt es drei wichtige Gründe, warum ich immer noch erwägen würde, eine Bibliothek eines Drittanbieters explizit einzuschließen - keiner davon würde auf die Verwendung eines Tools oder Frameworks hinweisen:
- Die spezifische Bibliothek ist nicht intrinsische an die Anwendung.
- Es wäre sehr teuer zu tauschen, ohne es einzuwickeln.
- Ich mag die API selbst nicht.
Wenn ich in all diesen drei Bereichen keine Level-Bedenken habe, unternehmen Sie keine nennenswerten Anstrengungen, um das Ganze zusammenzufassen. Und wenn Sie in allen drei Bereichen Bedenken haben, hilft ein automatisch generierter dünner Wrapper nicht wirklich.
Wenn Sie sich entschieden haben, eine Bibliothek zusammenzufassen, besteht die effizienteste und effektivste Verwendung Ihrer Zeit darin , Ihre Anwendung anhand der von Ihnen gewünschten Schnittstelle zu erstellen . nicht gegen eine vorhandene API.
Anders ausgedrückt, beachten Sie den klassischen Rat: Verschieben Sie jede Entscheidung, die Sie treffen können. Erstellen Sie zuerst den "Kern" Ihrer Anwendung. Code gegen Schnittstellen, die irgendwann das tun, was Sie wollen, was irgendwann von "peripheren Dingen" erfüllt wird, die es noch nicht gibt. Überbrücken Sie die Lücken nach Bedarf.
Diese Anstrengung mag sich nicht zeitsparend anfühlen . Wenn Sie jedoch das Gefühl haben, einen Wrapper zu benötigen, ist dies der effizienteste Weg, dies sicher zu tun .
Denk darüber so.
Sie müssen Code für diese Bibliothek in einer dunklen Ecke Ihres Codes verwenden - auch wenn dieser abgeschlossen ist. Wenn Sie die Bibliothek während des Testens verspotten, ist ein manueller Aufwand unvermeidlich - auch wenn sie eingepackt ist. Dies bedeutet jedoch nicht, dass Sie diese Bibliothek im Großteil Ihrer Anwendung direkt mit ihrem Namen bestätigen müssen .
TLDR
Wenn es sich lohnt, die Bibliothek zu verpacken, verwenden Sie Taktiken , um weitverbreitete direkte Verweise auf die Bibliothek Ihres Drittanbieters zu vermeiden. Verwenden Sie jedoch keine Abkürzungen, um dünne Wrapper zu generieren. Erstellen Sie zuerst Ihre Geschäftslogik, achten Sie auf Ihre Schnittstellen und entwickeln Sie Ihre Adapter nach Bedarf organisch .
Und wenn es darum geht, haben Sie keine Angst vor Integrationstests. Sie sind etwas unübersichtlicher, bieten aber immer noch Beweise für den Arbeitscode und können immer noch leicht dazu gebracht werden, Regressionen in Schach zu halten.