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?
architecture
fstuijt
źródło
źródło
DataSourceA
iDataSourceB
już odłączony?DataSourceA
ma zależność zarównoSubSystemA.1
aSubSystemA.2
, ale nie naDataSourceB
.SubsystemA.1
aby użyć czegoś innego niżDataSourceB
,DataSourceA
nie będę wiedział.DataSourceA
dba tylko o to, żeSubsystemA.1
magetFoo(id)
metodę. Istnieje abstrakcja międzyDataSourceA
iDataSourceB
.Odpowiedzi:
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.
źródło
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
A
iB
, 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:
A
iB
wykonać ją, podwajając wymagania dotyczące miejsca.źródło
DataSourceA
iDataSourceB
już odłączony?DataSourceA
ma zależność zarównoSubSystemA.1
aSubSystemA.2
, ale nie naDataSourceB
.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(...)
ifindBar(...)
. To jest interfejs do warstwy I / O.Twój opis źródeł danych wynika, że istnieją dwa sposoby na:
findFoo
ifindBar
i jedna metoda na B:findFooAuxiliaryInformation
. WfindFoo
bę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
, iFooAuxData
. Sprzężenie pomiędzyFoo
iFooAuxData
jest właściwe w danych wejściowych, a nie mogą być zmniejszone. Ale to połączenie powinno pojawić się tylko wfindFoo
metodzie. To najlepsze, co możesz zrobić. Wymaganie jest realizowane w jednym miejscu. Jeśli to się zmieni, musisz zmienić ten kod.źródło
Nie możesz
Jeśli dobrze rozumiem
Foo
iBar
pochodzędsA
.Bar
należą doFoo
s.Korzystnie, nie chcesz
Bar
s przypisaneFoo
s, chyba żeFoo
zostało uzupełnioneFoo.enhancedInfo
że pochodzi zdsB
.Twoje preferencje dotyczące przypisywania
Bar
s doFoo
s 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
dsB
zawierać lub nie mieć informacji na dany temat,Foo
a nawetdsB
mogą 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 obiektuFoo
+Bar
lub nie. Zezwolenie na dostarczenie niez ulepszonegoFoo
tylko komplikuje logikę i mówi mi, że preferencje nie są tak surowe, jak mogą się wydawać. Określić, jakie wariantyFoo
,Foo.enhanced
orazBar
aplikacja (s) może obsługiwać i będziesz miał swoją ostateczną odpowiedź.Istnieją inne rzeczy, które możesz zrobić, aby
Foo
zbliż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
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ć.
źródło