Rodzaje przedmiotów
Na potrzeby naszej dyskusji podzielmy nasze obiekty na trzy różne rodzaje:
Są to obiekty, które wykonują pracę. Przenoszą pieniądze z jednego konta czekowego na drugie, realizują zamówienia i wszystkie inne działania , których realizacji oczekujemy od oprogramowania biznesowego.
Obiekty logiki domeny zwykle nie wymagają akcesoriów (modułów pobierających i ustawiających). Zamiast tego tworzysz obiekt, przekazując zależności przez konstruktor, a następnie manipulujesz nim metodami (powiedz, nie pytaj).
Obiekty przesyłania danych są stanem czystym; nie zawierają żadnej logiki biznesowej. Zawsze będą mieć akcesoria. Mogą mieć setery, ale nie muszą, w zależności od tego, czy piszesz je w niezmienny sposób. Albo ustawisz swoje pola w konstruktorze, a ich wartości nie zmienią się przez cały okres istnienia obiektu, lub twoje akcesoria będą odczytywane / zapisywane. W praktyce obiekty te zazwyczaj można modyfikować, aby użytkownik mógł je edytować.
Obiekty modelu widoku zawierają reprezentację danych do wyświetlania / edycji. Mogą zawierać logikę biznesową, zwykle ograniczoną do sprawdzania poprawności danych. Przykładem obiektu View Model może być InvoiceViewModel, zawierający obiekt Customer, obiekt nagłówka faktury i elementy wiersza faktury. Obiekty modelu widoku zawsze zawierają akcesoria.
Zatem jedynym rodzajem obiektu, który będzie „czysty” w tym sensie, że nie będzie zawierał akcesoriów polowych, będzie obiekt Logiki Domeny. Serializacja takiego obiektu zapisuje jego bieżący „stan obliczeniowy”, dzięki czemu można go później odzyskać w celu zakończenia przetwarzania. Wyświetl modele i DTO można dowolnie serializować, ale w praktyce ich dane są zwykle zapisywane w bazie danych.
Serializacja, zależności i sprzężenie
Chociaż prawdą jest, że serializacja tworzy zależności, w tym sensie, że trzeba dokonać deserializacji na zgodny obiekt, niekoniecznie musi to oznaczać konieczność zmiany konfiguracji serializacji. Dobre mechanizmy serializacji są ogólnym celem; nie dbają o to, jeśli zmienisz nazwę właściwości lub członka, o ile nadal może mapować wartości na członków. W praktyce oznacza to tylko, że należy ponownie serializować instancję obiektu, aby reprezentacja serializacji (xml, json, cokolwiek) była zgodna z nowym obiektem; żadne zmiany konfiguracji serializatora nie powinny być konieczne.
Prawdą jest, że obiekty nie powinny przejmować się sposobem ich serializacji. Opisałeś już jeden sposób oddzielenia takich obaw od klas domen: odbicie. Ale serializator powinien martwić się tym, jak serializuje i deserializuje obiekty; taka jest w końcu jego funkcja. Sposób, w jaki trzymasz swoje obiekty oddzielone od procesu serializacji, polega na tym, aby serializacja była funkcją ogólnego przeznaczenia , zdolną do działania na wszystkich typach obiektów.
Jedną z rzeczy, o których ludzie się mylą, jest to, że oddzielenie musi nastąpić w obu kierunkach. To nie; musi działać tylko w jednym kierunku. W praktyce nigdy nie można całkowicie oddzielić; zawsze jest jakieś sprzężenie. Luźne sprzężenie ma na celu ułatwienie konserwacji kodu, a nie usunięcie wszystkich zależności.
Podstawowym celem serializacji jest zapewnienie, że dane wytworzone przez jeden system mogą być wykorzystywane przez jeden lub więcej kompatybilnych systemów.
Najłatwiejszym i najbardziej niezawodnym podejściem do serializacji jest przełożenie danych na format agnostyczny typu, który utrzymuje strukturę w prostym i łatwym w obsłudze formacie. Na przykład najbardziej rozpowszechnione formaty serializacji (tj. JSON, XML) używają dobrze zdefiniowanego formatu tekstowego. Tekst jest prosty w produkcji, transmisji i zużyciu.
Są dwa powody, dla których użycie jednego z tych formatów może nie być idealne.
Wydajność
Tłumaczenie wszystkich danych na ich tekstowe odpowiedniki wiąże się z nieodłącznym kosztem. Typy danych nie istniałyby, gdyby tekst był najbardziej wydajnym sposobem wyrażania wszystkich różnych form danych. Ponadto struktura tych formatów nie jest idealna do wyszukiwania podzbiorów danych asynchronicznie lub w częściach.
Na przykład XML i JSON zakładają, że używane dane będą zapisywane i odczytywane od początku do końca. W przypadku przetwarzania bardzo dużych zestawów danych, w których brakuje pamięci, system zużywający dane może wymagać możliwości przetwarzania danych w częściach. W takim przypadku może być wymagana implementacja serializacji / deserializacji specjalnego przeznaczenia do obsługi danych.
Precyzja
Rzutowanie wymagane do serializacji / deserializacji danych z zamierzonego typu na typ agnostyczny danych powoduje utratę precyzji.
Można argumentować, że tworzenie binarnej reprezentacji obiektów i danych jest zdecydowanie najbardziej wydajnym i dokładnym rozwiązaniem. Główną wadą jest to, że wdrożenie wszystkich systemów, które zarówno zużywają, jak i wytwarzają dane, muszą pozostać kompatybilne. Teoretycznie jest to proste ograniczenie, ale w praktyce jest to koszmar, ponieważ systemy produkcyjne z czasem się zmieniają / ewoluują.
To powiedziawszy. Oddzielenie serializacji / deserializacji od szczegółów specyficznych dla domeny ma sens jako ogólna zasada, ponieważ formaty ogólnego przeznaczenia są bardziej niezawodne, lepiej obsługiwane w różnych systemach i wymagają niewielkiego lub całkowitego zwiększenia nakładów związanych z konserwacją.
źródło