Czysta walidacja architektury w domenie a warstwa trwałości danych?


13

Studiuję czystość, w wyniku czego dość radykalnie zastanawiam się nad tym, jak projektuję i piszę oprogramowanie.

Wciąż mam problem z regułami biznesowymi, takimi jak: „przy zapisywaniu aktualizacji jakiegoś elementu, najpierw załaduj całą listę elementów, które mam uprawnienia do przeglądania / edycji itp., Potwierdź, że ten element jest na liście, oraz że kategoria pozycji nie jest obecnie zablokowana ((i inne reguły itp.) „), ponieważ jest to (złożona, ale nietypowa) reguła biznesowa, dlatego należy ją obsługiwać w domenie aplikacji, a nie wprowadzać logikę biznesową do warstwa db / trwałość.

Wydaje mi się jednak, że aby skutecznie sprawdzić te warunki, najlepiej będzie najlepiej obsłużyć ładnie spreparowane zapytanie db, zamiast ładować wszystkie dane do domeny aplikacji ...

Bez przedwczesnej optymalizacji, jakie jest zalecane podejście lub niektóre artykuły wuja Boba dotyczące tego pytania? A może powie „waliduj w domenie, dopóki nie stanie się to problemem”?

Naprawdę staram się znaleźć jakieś dobre przykłady / próbki dla czegoś innego niż najbardziej podstawowe przypadki użycia.

Aktualizacja:

Cześć wszystkim, dziękuję za odpowiedzi. Powinienem być bardziej przejrzysty, piszę oprogramowanie (głównie aplikacje internetowe) od dłuższego czasu, i zdecydowanie już doświadczyłem i zgadzam się ze wszystkimi tematami, które wspólnie opisujesz (weryfikacja przez backend, nie ufaj danym klienta, ogólnie mówiąc ścigaj się z surową wydajnością tylko wtedy, gdy jest to wymagane, ale potwierdź zalety narzędzi db, jeśli są dostępne, itp. itp.) i przeszedłem cykl uczenia się programisty od „zrzuć to wszystko”, aby „zbudować gigantyczny kontroler tłuszczu z aplikacjami N-poziomów” , a teraz naprawdę lubię i analizuję styl czystej / pojedynczej odpowiedzialności itp., zasadniczo w wyniku kilku projektów, które niedawno przekształciły się w dość niezgrabne i szeroko rozpowszechnione reguły biznesowe, gdy projekty ewoluowały i pojawiły się dalsze wymagania klientów.

W szczególności patrzę na czystą architekturę stylu w kontekście budowania apletów REST do obsługi klienta, a także do funkcji użytku wewnętrznego, w których wiele reguł biznesowych może być znacznie bardziej złożonych niż w zasadzie każdy przykład widziany w sieci (nawet przez samych architektów Clean / Hex).

Wydaje mi się, że naprawdę pytałem (i nie powiedziałem jasno) o to, w jaki sposób API Clean i REST będą siedzieć razem, gdzie większość rzeczy MVC, które widzisz w tych dniach, ma sprawdzanie poprawności żądań (np. Biblioteka FluentValidation w .NET), ale gdzie wiele z moje zasady „sprawdzania poprawności” to nie tyle ”to ciąg mniejszy niż 50 znaków„ ale więcej ”ten użytkownik wywołujący tę skrzynkę użytkownika / interactor może wykonać tę operację na tym zbiorze danych, biorąc pod uwagę, że jakiś powiązany obiekt jest obecnie zablokowany przez Zespół X do późniejszego miesiąca itp. itd. ”... tego rodzaju głęboko zaangażowane walidacje, w których stosuje się DUŻO obiektów domeny biznesowej i reguł domeny.

Czy powinienem przekształcić te reguły w określony rodzaj typu obiektu walidatora, który będzie towarzyszył każdemu interakcyjnemu przypadkowi użycia (zainspirowany projektem FluentValidator, ale z większą logiką biznesową i dostępem do danych), czy powinienem traktować walidację trochę jak bramę? umieść te walidacje w bramie (co moim zdaniem jest złe) itp. itp.

Dla porównania, mam zamiar się kilka artykułów takich jak ten , ale nie omawia Mattia walidacja dużo.

Wydaje mi się jednak, że krótka odpowiedź na moje pytanie przypomina odpowiedź, którą zaakceptowałem: „To nigdy nie jest łatwe i zależy”.


2
Często istnieje różnica między byciem „poprawnym” a byciem „praktycznym”. Biorąc pod uwagę wybór, który wolisz?
Robert Harvey

„ładuj całą listę elementów” nie wygląda jak reguła biznesowa, wydaje się, że zbytnio zagłębia się w szczegóły implementacji. Jeśli możesz spełnić regułę za pomocą zapytania db, bez wczytywania czegokolwiek, dlaczego reguła mówi „ładuj”?
Przestań krzywdzić Monikę

Odpowiedzi:


31

Sprawdzanie poprawności wprowadzania danych jest jedną z tych rzeczy, w których wszyscy zaczynają starać się, aby były czyste i (i jeśli są inteligentne) ostatecznie rezygnują, ponieważ istnieje tak wiele konkurujących ze sobą obaw.

  • Warstwa interfejsu użytkownika musi wykonać pewne formy sprawdzania poprawności bezpośrednio na stronie / formularzu klienta, aby zapewnić użytkownikowi informacje zwrotne w czasie rzeczywistym. W przeciwnym razie użytkownik spędza dużo czasu, czekając na informację zwrotną, podczas gdy transakcja jest wysyłana przez sieć.

  • Ponieważ klient często działa na niezaufanym komputerze (np. W prawie wszystkich aplikacjach internetowych), te procedury sprawdzania poprawności muszą zostać wykonane ponownie po stronie serwera, na którym kod jest zaufany.

  • Niektóre formy walidacji są niejawne z powodu ograniczeń wejściowych; na przykład pole tekstowe może pozwalać tylko na wprowadzanie liczb. Oznacza to, że możesz nie mieć „czy to numeryczne?” walidator na stronie, ale nadal będziesz potrzebować go gdzieś na zapleczu, ponieważ ograniczenia interfejsu użytkownika można ominąć (np. przez wyłączenie Javascript).

  • Warstwa interfejsu użytkownika musi wykonywać pewne formy sprawdzania poprawności na obwodzie usługi (np. Kod po stronie serwera w aplikacji internetowej), aby odizolować system przed atakami iniekcyjnymi lub innymi złośliwymi formami wprowadzania danych. Czasami ta weryfikacja nie znajduje się nawet w twojej bazie kodu, np . Sprawdzanie poprawności żądań ASP.NET .

  • Warstwa interfejsu użytkownika musi wykonać pewne formy sprawdzania poprawności, aby przekonwertować dane wprowadzone przez użytkownika na format zrozumiały dla warstwy biznesowej; na przykład musi przekształcić ciąg „6/26/2017” w obiekt DateTime w odpowiedniej strefie czasowej.

  • Warstwa biznesowa powinna wykonywać większość form sprawdzania poprawności, ponieważ, hej, teoretycznie należą one do warstwy biznesowej.

  • Niektóre formy sprawdzania poprawności są bardziej wydajne w warstwie bazy danych, szczególnie gdy potrzebne są sprawdzanie integralności referencyjnej (np. Aby upewnić się, że kod stanu znajduje się na liście 50 poprawnych stanów).

  • Niektóre formy sprawdzania poprawności muszą wystąpić w kontekście transakcji bazy danych ze względu na obawy dotyczące współbieżności, np. Zarezerwowanie unikalnej nazwy użytkownika musi być atomowe, aby inny użytkownik nie mógł jej pobrać podczas przetwarzania.

  • Niektóre formy sprawdzania poprawności mogą być wykonywane wyłącznie przez usługi stron trzecich, np. Podczas sprawdzania, czy kod pocztowy i nazwa miasta idą w parze.

  • W całym systemie kontrole zerowe i kontrole konwersji danych mogą występować na wielu warstwach, aby zapewnić rozsądne tryby awarii w przypadku błędów w kodzie.

Widziałem, jak niektórzy programiści próbowali skodyfikować wszystkie reguły sprawdzania poprawności w warstwie biznesowej, a następnie kazali innym warstwom wywołać je w celu wyodrębnienia reguł biznesowych i zrekonstruowania sprawdzania poprawności na innej warstwie. Teoretycznie byłoby wspaniale, ponieważ skończyłbyś z jednym źródłem prawdy. Ale nigdy nie widziałem, aby takie podejście robiło coś innego niż niepotrzebnie komplikowało rozwiązanie i często kończy się bardzo źle.

Jeśli więc zabijasz się, próbując dowiedzieć się, dokąd zmierza twój kod weryfikacyjny, radzimy - w praktycznym rozwiązaniu nawet umiarkowanie złożonego problemu, kod weryfikacyjny skończy się w kilku miejscach.


Jeśli uważasz, że zarządzasz interfejsem użytkownika za pomocą opinii wszystkich użytkowników, możesz po prostu przekazać większość sprawdzania poprawności w bazie danych i zachować tylko to, czego nie możesz zrobić w warstwie biznesowej. Problem powstaje, jeśli projektujesz pełny interfejs API zaplecza z bardzo szczegółowym rozwiązywaniem problemów.
Walfrat

2

Walidacja jest częścią warstwy biznesowej.

Chodzi o to: logika biznesowa w DAO unieważnia koncepcję DAO. Wykonanie sprawdzania poprawności w dowolnej wyższej warstwie spowoduje zbędne sprawdzanie poprawności, jeśli wywołasz operacje biznesowe z innego przypadku.

Może oceniasz pewne bezpieczeństwo w interfejsie użytkownika. Jest to jednak opcjonalne, ponieważ zabezpieczone obiekty domeny wykonają ważną pracę. W interfejsie użytkownika komponenty będą widoczne lub niewidoczne w zależności od uprawnień, które posiada aktualnie zalogowany użytkownik. Ale to tylko część doświadczenia użytkownika. Nie chcesz, aby użytkownik wpuszczał wyjątki bezpieczeństwa za każdym razem, gdy próbuje wykonać działanie, na które nie ma pozwolenia.


2

Możesz sprawdzić swoją perspektywę na temat tego, kto robi to, co w przypadku sprawdzania poprawności. Czy to DB, gdzie wiesz, że pracujesz z DB? A może jest to usługa (która jest wspierana i kontrolowana przez operacje DB). W moim projekcie każdy zagregowany katalog główny ma listę grup, które mogą go odczytać, oraz listę modyfikatorów. Gdy kod szuka określonego katalogu głównego lub listy katalogów głównych, które użytkownik może zobaczyć, wszystkie szczegóły są ukryte za usługą, która pobiera identyfikator użytkownika i dodatkowe części kontekstu wyszukiwania, np. Gdzie kafelek zaczyna się od „bla”. Kod nie dba o to, aby baza danych wykonała sprawdzenie istnienia, aby sprawdzić, czy grupy użytkowników istnieją w grupach czytelników. Oczekuje jedynie listy z treścią lub bez, opartej na tym, co kiedykolwiek zapewnia usługa, która jest określona tylko w umowie.

Dotyczy to wszystkich warstw. Kluczem jest ujednolicenie walidacji. Umieść jak najwięcej swojego potwierdzenia w domenie, jak to możliwe. Zwróć ograniczenia za pomocą interfejsu API. Do końca nie myślę o ograniczeniach pochodzących z biblioteki X lub pamięci Z, ale z usługi.


0

Jeśli jakaś logika sprawdzania poprawności jest wyrażona w najprostszy i najwyraźniejszy sposób w formie zapytania do bazy danych, to śmiało, masz odpowiedź. Jednak wydajność powinna stanowić problem, jeśli masz znany problem z wydajnością, w przeciwnym razie jest to przedwczesna optymalizacja.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.