Zacząłem myśleć o śledzeniu zmian w złożonym grafie obiektów w odłączonej aplikacji. Znalazłem już kilka rozwiązań, ale chciałbym wiedzieć, czy istnieje jakaś najlepsza praktyka lub jakiego rozwiązania używasz i dlaczego? Przekazałem to samo pytanie MSDN forum, ale otrzymałem tylko jedną odpowiedź. Chciałbym uzyskać więcej odpowiedzi na podstawie doświadczeń innych programistów.Śledzenie zmian na skomplikowanym obiekcie graficznym
To pytanie jest związane z .NET, więc odpowiedzi na pytania dotyczące implementacji preferuję odpowiedzi związane ze światem .NET, ale myślę, że jest tak samo na innych platformach.
Problem teoretyczny w moim przypadku jest zdefiniowana w wielu warstwowej architektury (niekoniecznie n-tier w tej chwili), jak następuje:
- Warstwa repozytoriów wykorzystaniem ORM do czynienia z uporem (narzędzie ORM nie w tej chwili, ale najprawdopodobniej będzie to Entity Framework 4.0 lub NHibernate).
- Zestaw czystych klas (persistent ignorant = POCO, który jest odpowiednikiem POJO w świecie Java) reprezentujących obiekty domeny. Repozytoria zachowują te klasy i zwracają je jako wyniki zapytań.
- Zestaw usług domenowych współpracujących z domenami.
- Warstwa fasady definiująca bramę do logiki biznesowej. Wewnętrznie używa repozytoriów, usług domenowych i obiektów domeny. Obiekty domeny nie są odsłonięte - każda metoda elewacji używa zestawu wyspecjalizowanych obiektów przesyłania danych dla parametru i wartości zwracanej. Obowiązkiem każdej metody elewacji jest przekształcenie domeny na DTO i odwrotnie.
- Nowoczesna aplikacja internetowa wykorzystująca warstwę elewacji i DTO - tę aplikację rozłączam. Zasadniczo projektowanie może się zmienić w przyszłości, aby warstwa fasady była opakowana przez warstwę usługi WWW, a aplikacja internetowa zużyje te usługi => przejście na trójwarstwowe (sieć, logika biznesowa, baza danych).
Załóżmy teraz, że jednym z obiektów domeny jest Zamówienie, które zawiera szczegóły zamówienia (wiersze) i powiązane zamówienia. Kiedy klient żąda Zlecenia na edycję, może modyfikować Zamówienie, dodawać, usuwać lub modyfikować szczegóły Zamówienia oraz dodawać lub usuwać powiązane Zamówienia. Wszystkie te modyfikacje są wykonywane na danych w przeglądarce internetowej - javascript i AJAX. Wszystkie zmiany są następnie przesyłane jednym kliknięciem, gdy klient naciska przycisk zapisu. Pytanie brzmi, jak poradzić sobie z tymi zmianami? Narzędzia repozytorium i narzędzia ORM muszą wiedzieć, które jednostki i relacje zostały zmodyfikowane, wstawione lub usunięte. Skończyłem z dwoma "najlepszymi" rozwiązaniami:
Przechowywać stan początkowy DTO w ukrytym polu (w najgorszym przypadku sesji). Po otrzymaniu żądania zapisania zmian utwórz nowy DTO na podstawie odebranych danych i drugiego DTO na podstawie utrwalonych danych. Połącz tych dwóch i śledź zmiany. Wyślij połączone DTO do warstwy elewacji i użyj otrzymanych informacji o zmianach, aby prawidłowo skonfigurować wykres jednostek. Wymaga to ręcznego śledzenia zmian w obiekcie domeny, dzięki czemu informacje o zmianach mogą być konfigurowane od podstaw, a następnie przekazywane do repozytorium - to jest kwestia, z której nie jestem zadowolony.
Nie śledzić zmian w DTO. Po otrzymaniu zmodyfikowanych danych w warstwie elewacji utwórz zmodyfikowany obiekt i załaduj aktualny stan z repozytorium (generalnie dodatkowe zapytanie do bazy danych - to jest punkt, z którego nie jestem zadowolony) - scalenie tych dwóch elementów i automatyczne śledzenie zmian za pomocą proxy podmiotu udostępnianego przez narzędzie ORM (Na to pozwala framework Entity 4.0 i NHibernate). Podczas obsługi współbieżności należy zachować szczególną ostrożność, ponieważ rzeczywisty stan nie musi być stanem początkowym.
Co o tym sądzisz?Co polecasz?
Wiem, że niektórych z tych wyzwań można uniknąć, używając buforowania na niektórych warstwach aplikacji, ale jest to coś, czego nie chcę obecnie używać.
Moje zainteresowanie tym tematem idzie nawet dalej. Załóżmy na przykład, że aplikacja przechodzi do architektury trójwarstwowej, a klient (aplikacja internetowa) nie zostanie zapisany w klasach .NET = DTO nie można ponownie użyć. Śledzenie zmian w DTO będzie znacznie trudniejsze, ponieważ wymagać będzie, aby inny zespół programistów prawidłowo wdrożył mechanizm śledzenia w swoich narzędziach programistycznych.
Uważam, że te problemy muszą zostać rozwiązane w wielu aplikacjach, podziel się doświadczeniem.
Witam, dziękuję za bardzo dobrą odpowiedź. Lubię to. Jest bardzo blisko mojej architektury, z tym wyjątkiem, że w moim przypadku używam DTO między UI a BL i obiektami/obiektami Domain między BL i DAL. Rozumiem twoje wyjaśnienie Jedyny punkt, którego mi brakuje to odpowiedź na główne pytanie - jak śledzić zmiany na złożonym grafiku obiektu? Otrzymujesz DTO i musisz jakoś znaleźć to, co się zmieniło. Jeśli twój DTO jest prostym obiektem, nie musisz go śledzić, ale co z DTO, który zawiera zbiór innych DTO? Musisz wiedzieć, co zmieniło się w tej kolekcji. –
RE zmian w obiekcie Wykres - oczekuję Istnieją wzorce projektowe, które poradzą sobie z tym, ale nie mogę sobie przypomnieć z góry mojej głowy - Momento przychodzi mi do głowy, inaczej może być modelem napędzanym zdarzeniami? –
W tradycyjnym modelu ASP.NET strony są zwykle budowane od zera za każdym razem (a więc ładujesz wszystkie dane bez względu na to, co się zmieniło), a jeśli zachowujesz dane w widoku, to traktujesz to jako "dane" - więc nie byłem w stanie chcieć szukać konkretnych zmian w sposobie, w jaki sugerujesz (?). Inne podejście jest oparte na technologii AJAX, ale jest podobne.Wzrok obserwatora również może być interesujący. –