2009-09-25 8 views
11

Powiedzmy mam poco tak:Czy powinienem umieścić logikę walidacji w POCO?

public class Name 
{ 
    public string FirstName { get; set; } 
    public string LastName { get; set; } 
} 

Imię i Nazwisko nie może być null. Dodam w metodzie tak:

public List<Error> Validate() 
{ 
    var errors = new List<Error>(); 

    if (String.IsNullOrEmpty(FirstName)) 
     errors.Add(new Error("FirstName", "You must fill out first name.")); 
    if (String.IsNullOrEmpty(LastName)) 
     errors.Add(new Error("LastName", "You must fill out last name.")); 
} 

gdzie Error to struktura, która zawiera NameValueDictionary. Czy to dobry sposób robienia rzeczy? Mogę potencjalnie zobaczyć problem z repozytorium, w którym ktoś próbuje zapisać to POCO bez uruchamiania go najpierw przez Validate().

Odpowiedz

2

Należy rozważyć zastosowanie aspektowego systemu sprawdzania poprawności, takiego jak xVal.

Zamiast konieczności włączania zasad sprawdzania poprawności bezpośrednio do kodu, można dodać je jako atrybuty właściwości i odciąć zależność. Twoja klasa będzie wyglądać następująco:

public class Name 
{ 
    [Required] 
    public string FirstName { get; set; } 
    [Required] 
    public string LastName { get; set; } 
} 

Aby bardziej bezpośrednio odpowiedzieć na pytanie, dodając reguły sprawdzania poprawności do POCO to prosty sposób robienia rzeczy, które będą działać, ale może dostać ciężki do utrzymania, i będziesz trzeba wymusić interfejs sprawdzania poprawności we wszystkich obiektach, co jest jego własnym bólem głowy. Rozwiązanie zorientowane na aspekt jest dość eleganckim rozwiązaniem, które rozwiązuje te problemy i wiele innych.

+1

Zajrzałem do xVal wcześniej, ale znalazłem wyraźny brak dokumentacji i przykładów. Być może zajrzę do tego jeszcze raz, gdy używam POCO. –

+0

Teraz, kiedy o tym myślę, w jaki sposób poradzisz sobie z przypadkami, w których potrzebujesz bardziej zaawansowanej weryfikacji, na przykład sprawdzając, czy ciąg ścieżki pliku wskazuje na fizyczny plik na dysku twardym? –

+0

xVal pozwala tworzyć niestandardowe atrybuty sprawdzania poprawności. Oto przykładowa strona: http://blog.codeville.net/2009/02/27/xval-08-beta-now-released/ – womp

3

Nie zrobiłbym tego. Moje POCO mają różną walidację na podstawie ich kontekstu. "Obiekty Moje osoby muszą mieć adres w tej aplikacji, ale muszą mieć tylko numer telefonu w tej innej aplikacji" ... to coś, na co chcesz mieć oko i być elastycznym.

Jestem zwolenniczką anemicznego modelu domeny, ponieważ zazwyczaj ponownie używam tej samej domeny, ale przypisuję różne zachowania i walidację na podstawie kontekstu (które mogą nawet być różnymi obszarami tej samej aplikacji).

Kiedy wdrażam nowe funkcje, zazwyczaj patrzę na moją klasę i zadaję sobie to pytanie: czy wydaje się to obowiązkiem tej klasy, czy byłoby bardziej odpowiednie dla klasy z innym zestawem obowiązków? Nazywamy to sprawdzaniem "Cecha zazdrości" i skutecznie pomaga oddzielić to, co klasa jest i nie jest zaniepokojona.

+0

Bardzo zgadzam się z drugim akapitem. To jest dokładnie powód, dla którego silniki reguł stały się popularne. – womp

+3

Anemiczne modele domen są bezużyteczne. Koniec końców, przekodowujesz tę samą logikę biznesową wszędzie. To właściwie antipattern według Martina Fowlera. A model anemiczny to nic innego jak DTO. – Andy

+1

Podczas gdy komentarze są stare, pomyślałem, że byłoby pomocne dodanie linku do [tego, co Andy ma na myśli] (http://martinfowler.com/bliki/AnemicDomainModel.html). – Derek

0

Nie znajduję niczego złego wprowadzając walidację do modelu. Działa dobrze z wszystkimi technologiami interfejsu użytkownika Microsoft, które oczekują, że model będzie mógł zostać zapytany, czy jest prawidłowy czy nie, i nie zachowuje odwzorowania jednego DTO na inny, tylko po to, aby powtórzyć weryfikację w widoku lub edytować model (lub gorzej, TYLKO stawiając go tam).

Zasady w twojej próbce są proste, ale często będziesz musiał napisać bardziej złożone reguły. Powinieneś prawdopodobnie sprawdzić framework Csla.Net.

Powiązane problemy