So reduzieren Sie die enge Kopplung zwischen zwei Datenquellen

10

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?

http://i.stack.imgur.com/Xi4aA.png

fstuijt
quelle
10
Das ist eine schöne Skizze. Mit welchem ​​Programm haben Sie es gezeichnet?
Marcelo MD
Ich möchte auch wissen, mit welchem ​​Programm Sie es gezeichnet haben. Bitte.
Tulains Córdova
2
yuml.me ist die Site, auf der er höchstwahrscheinlich das Diagramm erstellt hat.
Jason Turner
1
Sind Sie nicht DataSourceAund DataSourceBbereits entkoppelt? DataSourceAhat eine Abhängigkeit von beiden SubSystemA.1und SubSystemA.2, aber nicht von DataSourceB.
Tulains Córdova
1
@fstuijt Nein, das ist es nicht. Wenn Sie ändern SubsystemA.1, um etwas anderes als zu verwenden DataSourceB, DataSourceAwürde nicht wissen. DataSourceAkümmert sich nur darum, dass SubsystemA.1eine getFoo(id)Methode hat. Es gibt eine Abstraktion zwischen DataSourceAund DataSourceB.
Tulains Córdova

Antworten:

3

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.

KeithS
quelle
Diese Antwort deckt das Problem, auf das ich gestoßen bin, am besten ab und bietet meiner Meinung nach auch die bisher beste Antwort. Ich würde jedoch denken, dass das Kombinieren von Daten aus mehreren Quellen ein häufiges Problem ist. Irgendwelche Designmuster, die helfen könnten?
fstuijt
1
Einige Variationen eines Factory-Musters könnten nützlich sein. Wenn Sie über ein CloudInvoice- und ein SqlInvoice-Objekt (aus den jeweiligen Datenquellen) verfügen und eine einzelne einheitliche Rechnung erstellen möchten, erstellen Sie eine Factory, die über beide Datenquellen ausreichend Bescheid weiß, um jede Hälfte des zu erstellenden Datensatzes abzurufen führt die Informationen in Ihrer Domain-Klasse zusammen.
KeithS
4

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 Aund B, 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:

  • Die Datenmenge kann unerschwinglich sein - Eine vollständige Kopie von Aund Bmuss erstellt werden, wodurch sich der Platzbedarf verdoppelt.
  • Die Daten müssen aktiv sein - Es gibt Zeiträume zwischen der Änderung der Daten in der Quelle und der Weitergabe durch den Aggregationsjob an die aggregierte Quelle.
  • Sie müssen die Daten mit den ursprünglichen Quellen abgleichen. Die Aufgabe, die Änderungen wieder an ihre ursprünglichen Stellen zu verschieben, wird viel komplexer, wenn Sie diesen Ansatz wählen.
dasblinkenlight
quelle
Ich stimme zu, die Einführung einer Abstraktionsschicht ist der bevorzugte Ansatz
Neontapir
2
Sie können eine Abstraktionsschicht haben, ohne die Daten zu kopieren.
smp7d
@ smp7d Dies würde die Kupplung hinter einem schönen Frontend verstecken; Ich ging jedoch davon aus, dass Sie in Ihrem System bereits so etwas getan haben, da sich die Komplexität sonst auf Ihr gesamtes Design verteilen würde.
Dasblinkenlight
Abhängig von der DB-Umgebung kann dies auch mit einer oder mehreren Ansichten behandelt werden, sodass keine Daten mehr kopiert werden müssen.
Walter
Sind Sie nicht DataSourceAund DataSourceBbereits entkoppelt? DataSourceAhat eine Abhängigkeit von beiden SubSystemA.1und SubSystemA.2, aber nicht von DataSourceB.
Tulains Córdova
1

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(...)und findBar(...). Das ist die Schnittstelle zur E / A-Schicht.

Ihre Beschreibung der Datenquellen impliziert , dass es zwei Methoden , die auf A: findFoound findBarund ein Verfahren auf B: findFooAuxiliaryInformation. In müssen findFooSie 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, Foound FooAuxData. Die Kopplung zwischen Foound FooAuxDataist den Eingabedaten inhärent und kann nicht reduziert werden. Diese Kopplung sollte jedoch nur in der findFooMethode 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.

Kevin Cline
quelle
0

Das kannst du nicht.

Wenn ich es richtig verstehe Foound von Barkomme dsA. Bars gehören zu Foos.
Vorzugsweise wollen Sie nicht Bars zugewiesen Foos, es sei denn , die Foodurch einen Nachtrag ergänzt wurde Foo.enhancedInfodas kommt dsB.

Ihre Präferenz für die Zuweisung von Bars zu Foos 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 dsBmöglicherweise Informationen zu einem bestimmten Thema vorhanden sind oder nicht Foound dass diese dsBmöglicherweise nicht einmal verfügbar sind.

Sie müssen entscheiden, wie hart und schnell diese Präferenz Foo.enhancedInfowirklich ist. Basierend auf dieser Anforderung können Sie entscheiden, ob Sie ein Foo+ Bar-Objekt bereitstellen möchten oder nicht. Das Zulassen einer nicht erweiterten Version Fooerschwert nur die Logik und sagt mir, dass die Einstellung nicht so streng ist, wie es scheint. Bestimmen Sie, welche Varianten von Foo, Foo.enhancedund BarIhre Anwendung (en) unterstützen können, und Sie haben Ihre endgültige Antwort.

Es gibt andere Dinge, die Sie tun können, um die Foozugehö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
Umgekehrt
@fstuijt Ich werde meine Antwort gleich aktualisieren. Grundsätzlich wird es gleich bleiben. Sie müssen entscheiden, wie Sie Bar + Foo's bedienen möchten.
0

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.

smp7d
quelle