Wir sind von einem Drittanbieter abhängig, der eine gigantische Schnittstelle bereitstellt, für die wir nur drei Methoden benötigen. Außerdem ändert sich die Benutzeroberfläche häufig ...
Ich habe beschlossen, die Schnittstelle in eine Klasse in unserem Projekt einzuschließen und nur die Methoden bereitzustellen, die wir benötigen.
Ich bin mir jedoch nicht sicher, wie ich mit den Rückgabewerten umgehen soll ... Die Schnittstelle gibt ein Objekt vom Typ zurück Storage
. Wir haben intern einen Typ, StorageModel
der unsere interne Darstellung von a ist Storage
.
Was würden Sie im Mapper zurückgeben: Storage
oder StorageModel
? Wir haben einen DataService, StorageService
der eine Abhängigkeit des injizierten Wrappers erhält.
Momentan mache ich es im Grunde so:
public class StorageService
{
private readonly IExternalStorageWrapper externalStorageWrapper;
public StorageService(IExternalStorageWrapper externalStorageWrapper)
{
this.externalStorageWrapper = externalStorageWrapper;
}
public StorageModel GetStorage(int storageId)
{
return this.externalStorageWrapper.GetStorage(storageId).ConvertToStorageModel();
}
}
public class ExternalStorageWrapper : IExternalStorageWrapper
{
public Storage GetStorage(int storageId)
{
using(var ext = new ExternalStorage())
{
return ext.GetStorage(storageId);
}
}
}
Was würdest du sagen:
- Ist es gut wie oben, dass der Wrapper das externe
Storage
Objekt und der interne das interneStorageService
zurückgibtStorageModel
? - Oder würden Sie bereits eine
StorageModel
in der Verpackung zurückgeben?
Antworten:
Meiner Meinung nach sollte sich der Wrapper mit allen Dingen befassen, die mit der externen Bibliothek zusammenhängen. Dies bedeutet, dass die öffentliche Schnittstelle des Wrappers keine externen Typen benennen darf.
Das Zuordnen externer Typen zu den jeweiligen Typen Ihrer Anwendung ist Teil der Aufgaben des Wrappers. Wenn dies keine triviale Operation ist, können Sie die verschiedenen verfügbaren Tools verwenden, um das Problem zu zerlegen, z. B. das Injizieren eines Übersetzerobjekts. Der Übersetzer muss jedoch weiterhin Teil Ihres Wrapper-Moduls sein, und kein anderer Teil Ihrer Anwendung darf davon abhängen.
Auf diese Weise ist der Rest Ihrer Anwendung nicht nur gegen Änderungen in der Bibliothek, sondern auch gegen das Ersetzen der Bibliothek durch eine andere völlig immun.
quelle
Das ist ok. Dies wird auch als Adapter bezeichnet .
Sie wählen das Adaptermuster , daher besteht das Ziel hier darin , eine Schnittstelle (Bibliotheksmodell) in eine andere (Domänenmodell) umzuwandeln . Wenn also etwas von dem ersteren das Domänenmodell erreicht, erfüllt der Adapter seinen Zweck nicht .
Gemäß den vorherigen Argumenten sollte der Adapter das zurückgeben
StorageModel
.Letztendlich "spricht" Ihre Domain eine bestimmte Sprache, in der
Storage
sich ein Fremder befindet .Der Schlüssel hier ist zu wissen, aus welchem Grund Sie die Bibliothek verpacken / anpassen .
Adapter-, Dekorations- und Fassadenmuster haben möglicherweise Ähnlichkeiten, sind jedoch ziemlich unterschiedlich. So unterschiedlich wie die Probleme, die sie lösen.
Das heißt, Sie könnten auch interessiert sein an:
Fassadenmuster (Verstecken Komplexität)
Dekorationsmuster (Schnittstellenerweiterung) . Wann man es benutzt
Unterschiede zwischen Adaptermuster und Proxy-Muster .
Was ist eine Antikorruptionsschicht und wie wird sie verwendet? (Verstecken von minderwertigem und unordentlichem Code)
quelle
Sie können eine Bibliothek nicht effektiv verpacken, indem Sie sie duplizieren.
Was Sie einschließen sollten, ist Ihre Nutzung der Bibliothek und das bedeutet, dass Sie keine Objekte verfügbar machen, in diesem Fall Speicher. Versuchen Sie auch nicht, sie zu duplizieren.
Verwenden Sie die Bibliothek, aber halten Sie sie enthalten. Wenn Sie also in Ihrem Fall den StorageService zum Speichern von Dingen verwenden, sollten Sie ihn in Repositorys verpacken
Dabei ist MyPocoObject ausschließlich Ihre Daten- und Geschäftslogik. Keine Vervielfältigung von Speicher oder einem DataReader oder irgendetwas
quelle
Die Antwort ist, dass es davon abhängt, ob Sie jemals
Storage
direkt von einer Klasse aus zugreifen müssen, die es nicht istStorageModel
.Wenn Sie die Bibliothek umbrechen möchten, ist es sinnvoll, auch das von ihr zurückgegebene Objekt zu umschließen, damit Sie in Zukunft Änderungen an der Bibliothek vornehmen können. Wenn Sie jedoch jemals
Storage
direkt verwenden müssen, bedeutet dies, dass je nach Situation möglicherweise eine Rückkehr erforderlich istStorage
. Es könnte ein Argument dafür angeführt werden, dass dieStorage
Verwendung hier so vorgeschrieben ist, dassStorageModel
Sie wahrscheinlich während Ihres gesamten Programms konsistent bleiben möchten.Ich würde Ihnen dringend empfehlen, sowohl die Benutzeroberfläche als auch das zurückgegebene Objekt zu verpacken, wenn Sie dies nicht bereits tun. Dies ist jedoch nur dann sinnvoll, wenn Sie es nur im
StorageModel
gesamten Programm verwenden und nichtStorage
.quelle