Ich habe Probleme, eine geeignete Lösung für das folgende Architekturproblem zu finden.
In unserer Einstellung (unten skizziert) haben wir 2 Datenquellen, wobei Datenquelle A die Hauptquelle für Elemente vom Typ Foo ist. Es gibt eine sekundäre Datenquelle, mit der zusätzliche Informationen zu einem Foo abgerufen werden können. Diese Informationen sind jedoch nicht immer vorhanden.
Darüber hinaus kann die Datenquelle A zum Abrufen von Elementen vom Typ Bar verwendet werden. Jeder Balken bezieht sich jedoch auf ein Foo. Die Schwierigkeit hierbei ist, dass sich jeder Balken auf ein Foo beziehen sollte, das, falls verfügbar, auch die Informationen enthält, die durch die Datenquelle B erweitert wurden.
Meine Frage ist: Wie kann die enge Kopplung zwischen SubsystemA.1 und DataSourceB entfernt werden?
quelle
DataSourceA
undDataSourceB
bereits entkoppelt?DataSourceA
hat eine Abhängigkeit von beidenSubSystemA.1
undSubSystemA.2
, aber nicht vonDataSourceB
.SubsystemA.1
, um etwas anderes als zu verwendenDataSourceB
,DataSourceA
würde nicht wissen.DataSourceA
kümmert sich nur darum, dassSubsystemA.1
einegetFoo(id)
Methode hat. Es gibt eine Abstraktion zwischenDataSourceA
undDataSourceB
.Antworten:
Ich habe eine App mit fast derselben Datenarchitektur erstellt. Wir haben eine SQL-Datenbank vor Ort, die die meisten Automatisierungs- und internen Alltagsinformationen enthält, und dann einen Cloud-Service eines Drittanbieters, der für Vertrieb, Kontoverwaltung, Außendienstpersonal usw. verwendet wird. Der Helpdesk benötigte Informationen von beiden bezüglich der physischen Standorte der Kunden und Ausrüstung, und hatte es von zwei verschiedenen Anwendungen bekommen, bis ich eintrat.
Das lange und kurze ist, dass eine Datenquelle einen Verweis auf die Datensätze der anderen haben muss. In unserem Fall enthalten die Cloud-Daten von Drittanbietern Verweise auf die Daten vor Ort, da wir über diese Anordnung am meisten Kontrolle hatten. Mit einer ID für einen Datensatz aus einer der Datenquellen können wir jetzt Daten von beiden abrufen. Mit einer Cloud-ID ziehen wir den Datensatz aus der Cloud, rufen die Vor-Ort-ID ab und rufen die Vor-Ort-Daten ab. Mit einer Vor-Ort-ID fragen wir beide Datenquellen basierend auf dieser ID ab.
In meinem System habe ich keines der Objekte in der Domänenschicht zu einem untergeordneten Objekt des anderen gemacht. Bei jeder Verwendung der Daten aus beiden Speichern müssen zwei Objektinstanzen verwaltet werden. Keiner von beiden wird garantiert existieren, weshalb ich es so gemacht habe; Die App kann nur mit Cloud-Daten oder mit Vor-Ort-Daten oder beidem arbeiten. Je weniger Daten vorhanden sind, desto mehr Einschränkungen gelten.
Dies ist jedoch nicht schwer zu ändern, insbesondere wenn Sie sicher sind, dass immer eine Seite existieren wird. Fügen Sie einfach eine Eigenschaft in das Objekt ein, die die Seite darstellt, für die immer Daten vorhanden sind, dh vom Objekttyp, der den Datensatz des anderen Datenspeichers darstellt. Ein erweitertes "Zusammenführen" der beiden Diagramme zu einem ist möglich.
Diese Art der Anordnung muss notwendigerweise auf einer bestimmten Ebene gekoppelt sein. Sie können eine DAL haben, die mit beiden Datenspeichern verbunden werden kann, oder Sie können die DALs segmentieren, eine pro Datenspeicher, und eine höhere Schicht wie ein Controller kann die Daten von jedem abrufen und sie zusammenfassen. Auf einer bestimmten Ebene muss Ihr Programm jedoch über die nötigen Kenntnisse verfügen, um die Daten dieser beiden unterschiedlichen Datenquellen zusammenzufügen.
Sie können die in den meisten Fällen erforderliche Kopplung reduzieren, indem Sie Details darüber abstrahieren, woher die Daten stammen. Wenn Sie Daten von einem Webdienst erhalten, der Ihnen als Instanzen generierter Klassen zur Verfügung gestellt wird, setzen Sie einen Konverter ein, um eine tiefe Kopie der Dienstklasse in etwas zu erstellen, das Sie steuern, und das sich nicht ändern muss, wenn sich die Daten ändern Quelle tut (nur wenn das Schema tut).
Dies kann ein großes Unterfangen sein. Die von uns verwendete Cloud verfügt über Dutzende von Domänenklassen, von denen einige Hunderte von Datenfeldern aufweisen. Hier ist der Kicker: Möglicherweise müssen Sie sehr leicht große Änderungen am abstrakten Datentyp vornehmen, um einen Wechsel in eine andere Cloud oder eine andere Remote zu ermöglichen Datenquelle. Aus diesem Grund habe ich mich nicht darum gekümmert; Ich verwende die generierte Webdienstdomäne direkt und jetzt, da sich ein Wechsel von der Cloud zu einem externen (aber unter unserer Kontrolle stehenden) Datenspeicher abzeichnet, dessen Details ich noch nicht kenne, plane ich einfach, die Formulare und zu ändern Codebehinds der App, in der die Daten "kombiniert" werden, um das neue Schema und / oder die neuen Datenobjekte widerzuspiegeln. Es ist eine große Aufgabe, egal wie Sie es schneiden.
quelle
Eine Möglichkeit, damit umzugehen, besteht darin, eine aggregierte Datenquelle zu erstellen, die die Daten aus beiden Datenquellen an einem Ort enthält. Ein Job laufen würde regelmäßig auf Änderungen in den Quellen zu überprüfen
A
undB
, und die „Deltas“ in die aggregierten Datenquelle zu schreiben. Dies würde zwei eng gekoppelte Datenquellen in eine einzige kohärente Datenquelle umwandeln.Verschiedene Dinge könnten Sie daran hindern, diesen Ansatz zu wählen:
A
undB
muss erstellt werden, wodurch sich der Platzbedarf verdoppelt.quelle
DataSourceA
undDataSourceB
bereits entkoppelt?DataSourceA
hat eine Abhängigkeit von beidenSubSystemA.1
undSubSystemA.2
, aber nicht vonDataSourceB
.Es scheint, dass es auf der obersten Ebene zwei Typen gibt: Foo und Bar, und Sie haben nur zwei Aktionen auf der obersten Ebene:
findFoo(...)
undfindBar(...)
. Das ist die Schnittstelle zur E / A-Schicht.Ihre Beschreibung der Datenquellen impliziert , dass es zwei Methoden , die auf A:
findFoo
undfindBar
und ein Verfahren auf B:findFooAuxiliaryInformation
. In müssenfindFoo
Sie die Informationen von A und B zusammenführen.Ich bin mir nicht sicher, auf welche "enge Kopplung" Sie sich beziehen. Es gibt drei Datentypen in den beiden Datensätzen enthalten sind :
Bar
,Foo
undFooAuxData
. Die Kopplung zwischenFoo
undFooAuxData
ist den Eingabedaten inhärent und kann nicht reduziert werden. Diese Kopplung sollte jedoch nur in derfindFoo
Methode auftreten. Das ist das Beste, was Sie tun können. Die Anforderung wird an einem einzigen Ort implementiert. Wenn es sich ändert, müssen Sie diesen Code ändern.quelle
Das kannst du nicht.
Wenn ich es richtig verstehe
Foo
und vonBar
kommedsA
.Bar
s gehören zuFoo
s.Vorzugsweise wollen Sie nicht
Bar
s zugewiesenFoo
s, es sei denn , dieFoo
durch einen Nachtrag ergänzt wurdeFoo.enhancedInfo
das kommtdsB
.Ihre Präferenz für die Zuweisung von
Bar
s zuFoo
s ist das, was Ihre enge Kopplung erzeugt. Ich würde das als "Anforderungsherausforderung" qualifizieren, die Sie auf einen bestimmten Weg zwingt.Die technischen Herausforderungen bestehen also darin, dass
dsB
möglicherweise Informationen zu einem bestimmten Thema vorhanden sind oder nichtFoo
und dass diesedsB
möglicherweise nicht einmal verfügbar sind.Sie müssen entscheiden, wie hart und schnell diese Präferenz
Foo.enhancedInfo
wirklich ist. Basierend auf dieser Anforderung können Sie entscheiden, ob Sie einFoo
+Bar
-Objekt bereitstellen möchten oder nicht. Das Zulassen einer nicht erweiterten VersionFoo
erschwert nur die Logik und sagt mir, dass die Einstellung nicht so streng ist, wie es scheint. Bestimmen Sie, welche Varianten vonFoo
,Foo.enhanced
undBar
Ihre Anwendung (en) unterstützen können, und Sie haben Ihre endgültige Antwort.Es gibt andere Dinge, die Sie tun können, um die
Foo
zugehörigen Informationen näher zusammenzubringen, und die möglicherweise einige dieser Probleme lösen. Die Art und Weise, wie Ihre Frage formuliert ist, scheint sich auf Datenobjektebene mit dem Problem zu befassen, und Sie können Änderungen des Infrastrukturtyps möglicherweise nicht berücksichtigen.quelle
Wenn die Daten in Datenquelle B nicht für sich allein stehen können, möchten Sie sie wahrscheinlich nach Möglichkeit auf Datenquelle A migrieren.
Wenn sie unabhängig , aber miteinander verbundene sind, sollten Sie in aussehen Datenvirtualisierung . Auf diese Weise können Anwendungen die Daten (falls zutreffend) agnostisch als einen Satz behandeln. Abhängig von Ihrer Plattform wird wahrscheinlich ein Framework / eine Bibliothek vorhanden sein, die Ihnen bei der Implementierung helfen kann.
quelle