Jak zmniejszyć ścisłe powiązanie między dwoma źródłami danych

10

Mam problem ze znalezieniem właściwego rozwiązania następującego problemu dotyczącego architektury.

W naszym ustawieniu (naszkicowanym poniżej) mamy 2 źródła danych, gdzie źródło danych A jest podstawowym źródłem dla elementów typu Foo. Istnieje dodatkowe źródło danych, które można wykorzystać do uzyskania dodatkowych informacji na temat Foo; jednak ta informacja nie zawsze istnieje.

Ponadto źródło danych A można wykorzystać do wyszukiwania elementów typu Bar. Jednak każdy słupek odnosi się do Foo. Trudność polega na tym, że każdy pasek powinien odnosić się do Foo, które, jeśli jest dostępne, zawiera także informacje rozszerzone przez źródło danych B.

Moje pytanie brzmi: jak usunąć ścisłe powiązanie między podsystemem A.1 i DataSourceB?

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

fstuijt
źródło
11
To piękny szkic. Jakiego programu użyłeś, aby go narysować?
Marcelo MD,
Chcę również wiedzieć, jakiego programu użyłeś do jego narysowania. Proszę.
Tulains Córdova
2
yuml.me jest witryną, której użył bardziej niż prawdopodobne, aby stworzyć diagram.
Jason Turner
1
Nie są DataSourceAi DataSourceBjuż odłączony? DataSourceAma zależność zarówno SubSystemA.1a SubSystemA.2, ale nie na DataSourceB.
Tulains Córdova
1
@fstuijt Nie, to nie jest. Jeśli zmodyfikujesz, SubsystemA.1aby użyć czegoś innego niż DataSourceB, DataSourceAnie będę wiedział. DataSourceAdba tylko o to, że SubsystemA.1ma getFoo(id)metodę. Istnieje abstrakcja między DataSourceAi DataSourceB.
Tulains Córdova

Odpowiedzi:

3

Stworzyłem aplikację z tą samą architekturą danych; mamy lokalną bazę danych SQL zawierającą większość automatyzacji i wewnętrznych informacji z dnia na dzień, a następnie zewnętrzną usługę w chmurze używaną do sprzedaży, zarządzania kontem, personelu terenowego itp. Dział pomocy potrzebował informacji od obu dotyczących fizycznych lokalizacji klientów i sprzęt. Dostawałem go z dwóch różnych aplikacji, dopóki nie wkroczyłem.

Długie i krótkie jest to, że jedno źródło danych musi mieć odniesienie do zapisów drugiego. W naszym przypadku dane w chmurze stron trzecich zawierają odniesienia do danych na miejscu, ponieważ to układ, nad którym mieliśmy największą kontrolę. Teraz, mając identyfikator rekordu z dowolnego źródła danych, możemy uzyskać dane z obu; za pomocą identyfikatora w chmurze pobieramy rekord z chmury, uzyskujemy identyfikator u klienta i pobieramy dane u klienta. Za pomocą identyfikatora na miejscu sondujemy oba źródła danych na podstawie tego identyfikatora.

W moim systemie nie uczyniłem żadnego obiektu dzieckiem drugiego w warstwie domeny; każde użycie danych z obu sklepów musi utrzymywać dwie instancje obiektów. Żaden z nich nie istnieje, dlatego tak zrobiłem; aplikacja może działać tylko z danymi w chmurze, z danymi lokalnymi lub z obydwoma tymi elementami, im więcej ograniczeń, tym mniej danych ma.

Nie jest to jednak trudne do zmiany, zwłaszcza jeśli masz pewność, że jedna strona zawsze będzie istnieć; po prostu dołącz właściwość do obiektu reprezentującego stronę, dla której zawsze będą istnieć dane, to znaczy typu obiektu reprezentującego rekord innego magazynu danych. Możliwe jest bardziej zaawansowane „łączenie” dwóch wykresów w jeden.

Tego rodzaju układ musi koniecznie być sprzężony na pewnym poziomie. Możesz mieć DAL, który może łączyć się z oboma magazynami danych, lub możesz segmentować DAL, jeden na magazyn danych, i mieć wyższą warstwę, taką jak kontroler, który pobiera dane z każdego z nich i przyciąga je do siebie. Ale, na pewnym poziomie, twój program musi mieć spryt, by połączyć te dwa różne źródła danych.

W większości przypadków można zmniejszyć wymagane sprzężenie, wyodrębniając szczegóły dokładnie, skąd pochodzą dane. Jeśli otrzymujesz dane z usługi internetowej, która jest przekazywana jako instancje wygenerowanych klas, to umieść konwerter, aby utworzyć głęboką kopię klasy usługi w coś, co kontrolujesz, co nie będzie musiało się zmienić, jeśli dane robi to źródło (tylko jeśli schemat).

To może być ogromne przedsięwzięcie; chmura, której używamy, ma dziesiątki klas domen, z których niektóre mają setki pól danych, i - oto jest kicker - możesz bardzo łatwo wprowadzić duże zmiany w abstrakcyjnym typie danych, aby umożliwić przejście do innej chmury lub innego zdalnego źródło danych. Z tego powodu nie zawracałem sobie głowy; Korzystam bezpośrednio z wygenerowanej domeny usług internetowych, a teraz, gdy zbliża się zmiana z chmury na zewnętrzny (ale pod naszą kontrolą) magazyn danych, którego szczegółów wciąż nie znam, po prostu planuję zmienić formularze i kody aplikacji, w których dane są „łączone”, aby odzwierciedlić nowy schemat i / lub obiekty danych. To wielka praca, bez względu na to, jak ją pokroisz.

KeithS
źródło
Ta odpowiedź najlepiej obejmuje napotkany problem i moim zdaniem oferuje również najlepszą dotychczasową odpowiedź. Sądzę jednak, że łączenie danych z wielu źródeł jest częstym problemem. Jakieś wzorce projektowe, które mogą pomóc?
fstuijt
1
Przydałaby się pewna odmiana wzoru fabrycznego. Jeśli masz CloudInvoice i SqlInvoice obiekt (z ich odpowiednich źródeł danych) i chcesz utworzyć pojedynczą zunifikowaną fakturę, utwórz fabrykę, która wie wystarczająco dużo o obu źródłach danych, aby pobrać każdą połowę rekordu, który zamierza utworzyć, a następnie scala informacje w klasie domeny.
KeithS,
4

Jednym ze sposobów rozwiązania tego problemu jest utworzenie zagregowanego źródła danych, które zawiera dane z obu źródeł danych w jednym miejscu. Zadanie będzie uruchamiane okresowo w celu sprawdzenia zmian w źródłach Ai B, a pisząc „delty” do swojego zagregowanego źródła danych. To przekształciłoby dwa ściśle powiązane źródło danych w jedno spójne źródło danych.

Kilka rzeczy może powstrzymać cię przed przyjęciem tego podejścia:

  • Ilość danych może być wygórowana - należy wykonać pełną kopię Ai Bwykonać ją, podwajając wymagania dotyczące miejsca.
  • Dane muszą być aktywne - będą okresy między czasem, w którym dane w źródle uległy zmianie, a zadanie agregujące propagowało je do zagregowanego źródła.
  • Musisz pogodzić dane z oryginalnymi źródłami - zadanie przeniesienia zmian z powrotem do ich oryginalnych miejsc staje się o wiele bardziej złożone, jeśli zastosujesz takie podejście.
dasblinkenlight
źródło
Zgadzam się, wprowadzenie warstwy abstrakcji jest preferowanym podejściem
neontapir
2
Możesz mieć warstwę abstrakcji bez kopiowania danych.
smp7d,
@ smp7d To ukryłoby połączenie za ładnym frontem; Zakładałem, że robisz już coś takiego w swoim systemie, ponieważ w przeciwnym razie złożoność byłaby rozłożona na cały projekt.
dasblinkenlight
W zależności od środowiska DB można to również obsłużyć za pomocą jednego lub więcej widoków, eliminując potrzebę kopiowania danych.
Walter,
Nie są DataSourceAi DataSourceBjuż odłączony? DataSourceAma zależność zarówno SubSystemA.1a SubSystemA.2, ale nie na DataSourceB.
Tulains Córdova
1

Wygląda na to, że na najwyższym poziomie są dwa typy: Foo i Bar, a ty masz tylko dwie akcje na najwyższym poziomie: findFoo(...)i findBar(...). To jest interfejs do warstwy I / O.

Twój opis źródeł danych wynika, że istnieją dwa sposoby na: findFooi findBari jedna metoda na B: findFooAuxiliaryInformation. W findFoobędziesz musiał scalić informacje z A i B.

Nie jestem pewien, o jakim „ścisłym sprzężeniu” mówisz. Istnieją trzy typy danych zawartych w tych dwóch zestawów danych: Bar, Foo, i FooAuxData. Sprzężenie pomiędzy Fooi FooAuxDatajest właściwe w danych wejściowych, a nie mogą być zmniejszone. Ale to połączenie powinno pojawić się tylko w findFoometodzie. To najlepsze, co możesz zrobić. Wymaganie jest realizowane w jednym miejscu. Jeśli to się zmieni, musisz zmienić ten kod.

Kevin Cline
źródło
0

Nie możesz

Jeśli dobrze rozumiem Fooi Barpochodzę dsA. Barnależą do Foos.
Korzystnie, nie chcesz Bars przypisane Foos, chyba że Foozostało uzupełnione Foo.enhancedInfoże pochodzi z dsB.

Twoje preferencje dotyczące przypisywania Bars do Foos są tym, co tworzy ciasne połączenie. Kwalifikowałbym to jako „wyzwanie wymagań”, które zmusza cię do zejścia na określoną ścieżkę.

Wyzwania techniczne mogą więc dsBzawierać lub nie mieć informacji na dany temat, Fooa nawet dsBmogą nie być dostępne.

Musisz zdecydować, jak twarda i szybka jest ta preferencja Foo.enhancedInfo. W oparciu o to wymaganie możesz zdecydować o podaniu obiektu Foo+ Barlub nie. Zezwolenie na dostarczenie niez ulepszonego Footylko komplikuje logikę i mówi mi, że preferencje nie są tak surowe, jak mogą się wydawać. Określić, jakie warianty Foo, Foo.enhancedoraz Baraplikacja (s) może obsługiwać i będziesz miał swoją ostateczną odpowiedź.

Istnieją inne rzeczy, które możesz zrobić, aby Foozbliżyć powiązane informacje i które mogą rozwiązać niektóre z tych problemów. Sposób sformułowania pytania brzmi, jakbyś miał do czynienia z problemem na poziomie obiektu danych i możesz nie być w stanie rozważyć zmian typu infrastruktury.


źródło
W drugą stronę: foo należą do Bar s
fstuijt
@fstuijt Za chwilę zaktualizuję swoją odpowiedź. Zasadniczo pozostanie taki sam. Musisz zdecydować, w jaki sposób chcesz serwer Bar + Foo's.
0

Jeśli dane w źródle danych B nie są w stanie samodzielnie działać, prawdopodobnie chcesz migrować je do źródła danych A, jeśli to możliwe.

Jeśli są one niezależne, ale powiązane, powinieneś przyjrzeć się wirtualizacji danych . Umożliwi to aplikacjom traktowanie danych jako jednego zestawu (w stosownych przypadkach) w sposób agnostyczny. W zależności od platformy prawdopodobnie będzie istniał szkielet / biblioteka, która może pomóc Ci to zaimplementować.

smp7d
źródło