Łamałbyś zasadę DRY, umieszczając tę logikę sprawdzania poprawności wszędzie tam, gdzie używany jest kod pocztowy.
Z drugiej strony, w kontaktach z wieloma różnymi krajami i ich różnymi systemami kodów pocztowych, oznacza to, że nie można zweryfikować kodu pocztowego, chyba że znasz dany kraj. Twoja ZipCode
klasa musi także przechowywać kraj.
Ale czy następnie oddzielnie przechowujesz kraj jako część Address
(którego kod pocztowy jest również częścią) i część kodu pocztowego (do weryfikacji)?
- Jeśli to zrobisz, naruszysz również SUCHO. Nawet jeśli nie nazwiesz tego naruszeniem OSUSZANIA (ponieważ każda instancja ma inny cel), nadal niepotrzebnie zajmuje dodatkową pamięć, oprócz otwierania drzwi do błędów, gdy dwie wartości kraju są różne (co logicznie nigdy nie powinno być).
- Lub alternatywnie prowadzi to do konieczności zsynchronizowania dwóch punktów danych, aby upewnić się, że zawsze są one takie same, co sugeruje, że powinieneś naprawdę przechowywać te dane w jednym punkcie, a tym samym udaremnić cel.
- Jeśli tego nie zrobisz, to nie jest to
ZipCode
klasa, ale Address
klasa, która znowu będzie zawierała string ZipCode
co oznacza, że zatoczyliśmy pełne koło.
Na przykład mogę porozmawiać z analitykiem biznesowym na temat kodu pocztowego zamiast ciągu zawierającego kod pocztowy.
Zaletą jest to, że możesz o nich mówić, opisując model domeny.
Nie rozumiem twojego podstawowego twierdzenia, że gdy część informacji ma dany typ zmiennej, to w jakiś sposób masz obowiązek wspomnieć o tym typie, gdy rozmawiasz z analitykiem biznesowym.
Czemu? Dlaczego nie możesz po prostu mówić o „kodzie pocztowym” i całkowicie pomijać określony typ? Jakiego rodzaju rozmowy prowadzisz ze swoim analitykiem biznesowym (nie technicznym!), Gdzie typ nieruchomości jest kwintesencją rozmowy?
Skąd pochodzę, kody pocztowe są zawsze numeryczne. Mamy więc wybór, możemy przechowywać go jako int
lub jako string
. Zwykle używamy łańcucha, ponieważ nie oczekujemy operacji matematycznych na danych, ale nigdy analityk biznesowy nie powiedział mi, że musi to być łańcuch. Decyzję tę podejmuje deweloper (lub zapewne analityk techniczny, choć z mojego doświadczenia wynika, że nie zajmują się bezpośrednio drobiazgami).
Analityk biznesowy nie dba o typ danych, o ile aplikacja wykonuje to, czego oczekuje.
Walidacja jest trudną bestią do rozwiązania, ponieważ zależy od tego, czego oczekują ludzie.
Po pierwsze, nie zgadzam się z argumentem walidacyjnym jako sposobem pokazania, dlaczego należy unikać prymitywnej obsesji, ponieważ nie zgadzam się z tym, że (jako uniwersalna prawda) dane muszą być zawsze weryfikowane przez cały czas.
Na przykład, co jeśli jest to bardziej skomplikowane wyszukiwanie? Zamiast zwykłego sprawdzenia formatu, co jeśli weryfikacja wymaga skontaktowania się z zewnętrznym interfejsem API i oczekiwania na odpowiedź? Czy naprawdę chcesz zmusić aplikację do wywołania tego zewnętrznego interfejsu API dla każdego ZipCode
obiektu, który tworzysz?
Może jest to ścisły wymóg biznesowy, a następnie oczywiście uzasadniony. Ale to nie jest uniwersalna prawda. Będzie wiele przypadków użycia, w których będzie to bardziej obciążenie niż rozwiązanie.
Jako drugi przykład podczas wpisywania adresu w formularzu często podajesz swój kod pocztowy przed krajem. Chociaż miło jest mieć natychmiastowe informacje zwrotne dotyczące sprawdzania poprawności w interfejsie użytkownika, w rzeczywistości byłoby przeszkodą dla mnie (jako użytkownika), jeśli aplikacja powiadomiłaby mnie o „złym” formacie kodu pocztowego, ponieważ prawdziwym źródłem problemu jest (np.) To, że mój kraj nie jest krajem wybranym domyślnie, dlatego weryfikacja nastąpiła dla niewłaściwego kraju.
To zły komunikat o błędzie, który rozprasza użytkownika i powoduje niepotrzebne zamieszanie.
Podobnie jak wieczna walidacja nie jest uniwersalną prawdą, podobnie jak moje przykłady. To jest kontekstowe . Niektóre domeny aplikacji wymagają przede wszystkim weryfikacji danych. Inne domeny nie umieszczają walidacji tak wysoko na liście priorytetów, ponieważ problemy, które niesie ze sobą, są sprzeczne z ich rzeczywistymi priorytetami (np. Wrażenia użytkownika lub możliwość początkowego przechowywania wadliwych danych, aby można je było poprawić zamiast nigdy nie pozwalać na to przechowywane)
Data urodzenia: sprawdź, czy to więcej niż umysł i mniej niż dzisiejsza data.
Wynagrodzenie: sprawdź, czy jest większa lub równa zero.
Problem z tymi walidacjami polega na tym, że są one niekompletne, zbędne lub wskazują na znacznie większy problem .
Sprawdzanie, czy data jest większa niż umysł, jest zbędne. Umysł dosłownie oznacza, że jest to najmniejsza możliwa data. Poza tym, gdzie narysujesz linię istotności? Po co zapobiegać, DateTime.MinDate
ale pozwalać DateTime.MinDate.AddSeconds(1)
? Wybierasz konkretną wartość, która nie jest szczególnie zła w porównaniu do wielu innych wartości.
Moje urodziny są 2 stycznia 1978 r. (Nie, ale załóżmy, że tak). Powiedzmy jednak, że dane w Twojej aplikacji są nieprawidłowe, a zamiast tego napisano, że moje urodziny to:
- 1 stycznia 1978 r
- 1 stycznia 1722 r
- 1 stycznia 2355 r
Wszystkie te daty są nieprawidłowe. Żaden z nich nie jest „bardziej odpowiedni” niż drugi. Ale twoja reguła sprawdzania poprawności złapie tylko jeden z tych trzech przykładów.
Całkowicie pominąłeś także kontekst korzystania z tych danych. Jeśli jest to używane np. W bocie przypominającym o urodzinach, powiedziałbym, że walidacja nie ma sensu, ponieważ nie ma szczególnych złych konsekwencji dla podania niewłaściwej daty.
Z drugiej strony, jeśli są to dane rządowe i potrzebujesz daty urodzenia, aby uwierzytelnić czyjąś tożsamość (a ich niepodanie prowadzi do złych konsekwencji, np. Odmowy zabezpieczenia społecznego), to poprawność danych jest najważniejsza i musisz w pełni sprawdź poprawność danych. Proponowana walidacja, którą masz teraz, jest nieodpowiednia.
W przypadku wynagrodzenia istnieje pewien zdrowy rozsądek, ponieważ nie może być ujemny. Ale jeśli realistycznie oczekujesz, że wprowadzane są bezsensowne dane, sugerowałbym zbadanie źródła tych bezsensownych danych. Ponieważ jeśli nie można im ufać, że wprowadzają sensowne dane, nie można im również ufać, że wprowadzą prawidłowe dane.
Jeśli zamiast tego wynagrodzenie jest obliczane przez aplikację i w jakiś sposób możliwe jest uzyskanie liczby ujemnej (i poprawnej), wówczas lepszym rozwiązaniem byłoby Math.Max(myValue, 0)
przekształcenie liczb ujemnych w 0, zamiast nieudanej weryfikacji. Ponieważ jeśli twoja logika zdecydowała, że wynik jest liczbą ujemną, nieudana walidacja oznacza, że będzie musiała powtórzyć obliczenia, i nie ma powodu sądzić, że za drugim razem pojawi się inna liczba.
A jeśli pojawi się inna liczba, ponownie podejrzewasz, że obliczenia nie są spójne i dlatego nie można im ufać.
Nie oznacza to, że sprawdzanie poprawności nie jest przydatne. Ale bezcelowa walidacja jest zła, zarówno dlatego, że wymaga wysiłku, ale tak naprawdę nie rozwiązuje problemu, i daje ludziom fałszywe poczucie bezpieczeństwa.