2010-09-13 17 views
5

Jaki jest najlepszy sposób sprawdzania poprawności danych wejściowych? Ze względu na argument, jeśli dane wejściowe są nieprawidłowe, użytkownik chciałby wiadomość wyjaśniającą, dlaczego.Wzorzec do sprawdzania poprawności danych wejściowych?

Oto, co mogę wymyślić.

  • Validator metoda: Hasło wejście do walidatora, która zwraca true jeśli wejście jest prawidłowy. W przeciwnym razie walidator albo zwróci false (albo kod błędu) i umożliwi wywołującemu nieprawidłowe wprowadzanie danych. Lub weryfikator bierze odpowiedzialność za samo działanie. Lub walidator wywołuje metodę zwrotną. Wady: czynności podejmowane w celu sprawdzenia poprawności mogą się powtarzać po wywołaniu właściwej metody.

  • Przekaż dane wejściowe bezpośrednio do metody, bez sprawdzania poprawności. Pozwól, aby metoda obsługiwała nieprawidłowe komunikaty. Może wysłać wiadomość o błędzie bezpośrednio do użytkownika lub użyć metody wywołania zwrotnego. Po wysłaniu wiadomości metoda musi zwrócić lub rzucić wyjątek, aby przerwać przetwarzanie nieprawidłowych danych wejściowych. Klasa wywołująca będzie kontynuować do następnego wiersza wejścia. Wady: ta metoda ma teraz efekt uboczny wysyłania komunikatu o błędzie.

Jaka jest tutaj odpowiednia strategia? Zauważ, że nie uważam, że wyrzucanie wyjątków jest właściwe, ponieważ obsługa nieprawidłowych danych wejściowych jest podstawową funkcją aplikacji, co najmniej w moim przypadku:.

Odpowiedz

0

Nie powinieneś przekazywać danych wejściowych bezpośrednio do metody (myślę, że "metoda" oznacza jakąś logikę biznesową), aby być uczciwym, ponieważ łączy widok i model. Powinieneś zrobić to, aby stworzyć kontroler z metodą sprawdzania poprawności lub osobną klasą sprawdzania poprawności, która pobierałaby dane wejściowe i sprawdzała je za pomocą "zewnętrznych" metod. Następnie, w zależności od wyniku, kontroler/walidator może zwrócić błąd sprawdzania poprawności lub przesłać dane wejściowe gdziekolwiek chcesz. Największą zaletą tego, o czym mówiłem wcześniej, jest oddzielenie modelu od widoku. Model nie powinien wiedzieć nic o widoku (a jeśli chcesz zmienić widok, będziesz musiał przepisać swój model!). Nie jestem do końca pewien, dlaczego chciałbyś powielić kod walidacyjny w modelu biznesowym? Walidacja i nawigacja powinny być tym, co robi kontroler. Przynajmniej tak robi się wzór MVC.
Rzucanie wyjątków nie jest takie złe, ale należy je wrzucić do modelu i schwytać w kontrolerze. Na przykład masz system, w którym użytkownicy mają mieć unikalne loginy, użytkownik wprowadza login, który jest już w bazie danych, kontroler wywołuje metodę sprawdzania autentyczności, która próbuje (używając modelu) wstawić ją do bazy danych. Jeśli wszystko pójdzie dobrze, zostanie wstawione, a kontroler może zwrócić komunikat "Włożyłeś wartość z powodzeniem". Ale jeśli model zgłasza wyjątek (np. Błąd wyjątkowego naruszenia ograniczeń lub coś podobnego), kontroler powinien po prostu go złapać i zwrócić "ten login już istnieje w DB". W ten sposób model nie wie nic o widoku i można go ponownie użyć, a nie masz duplikacji kodu.

2

Zobacz strukturę powiązań i weryfikacji danych Spring. Rzeczywiście bardzo ładne i zaprojektowane tak, aby można je było używać samodzielnie lub jako część interfejsu użytkownika.

+0

W przypadku, ludzie potrzebują linku odsyłającego https : //docs.spring.io/spring/docs/current/spring-framework-reference/html/validation.html – Eternalcode

0
public interface Validator { 
    /** 
    * Validates a JComponent</code>. 
    * @param component 
    *  The component to validate. 
    * @param message 
    *  The message to display if the validation fails. 
    * @return 
    *  Returns <code>false</code> if the validation fails, and 
    *  <code>true</code> otherwise. 
    */ 
    boolean validate(JComponent component, String message); 
} 

Można mieć AbstractValidator (Rozszerza javax.swing.InputVerifier) ​​klasy, który nie obsługuje wyświetlania wiadomości obok JComponent z nieprawidłowym wpisu.Wystarczy popatrzeć na this przykład

0

teraz używam hibernacji ramy zatwierdzającego bardzo prosty i przydatnych:

I adnotacje klas z czego potrzebuję, a następnie użyć go:

Moja klasa podmiot:

public class Content { 

@NotNull 
private Heading heading; 

@NotNull 
@Length(max = 8) 
private String contentType; 

    // Everything else 

} 

My Validator Składnik:

@Component 
public class Validator implements IValidator { 
    protected static Log log = LogFactory.getLog(Validator.class); 

    javax.validation.Validator validator; 

    @Autowired 
    WebApplicationExceptionBuilder webApplicationExceptionBuilder; 

    public void validate (Object entity) throws WebApplicationException { 
     ValidatorFactory factory = Validation.buildDefaultValidatorFactory(); 
     validator = factory.getValidator(); 
     Set<ConstraintViolation<Object>> violations = validator.validate(entity); 
     if (!violations.isEmpty()) { 
      webApplicationExceptionBuilder 
         .raise("some fields are missing or incorrect", 
          violations); 
     } 
    } 

} 

Gdzie go używać:

public class Foo{ 

    @Autowired 
    private IValidator validator; 

    @Autowired 
    private IContentService contentService; 

    public void bar(Content c) throws Exception{ 
     validator.validate(c); 
     contentService.persist(content); 
    } 

} 
1

Miłym rozwiązaniem dla walidacji obiektów bez ciężaru tworząc wiele klas, które implementują interfejs „validator” lub za pomocą anonimowych klas wewnętrznych, które nie są wielokrotnego użytku, jest użyć stałej funkcjonalność wyliczenia:

W przykładzie:

public enum ObjectValidation { 

BAD_DATE_FORMAT(ErrorCode.BAD_DATE_FORMAT) { 

    @Override 
    boolean validate(String value, List<String> acceptableValues) { 
     boolean isValid = false; 
     // validate the date 
     SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy"); 
     try { 
      sdf.parse(value); 
      isValid = true; 
     } catch (ParseException ex) { 

     } 

     /* 
     * We could use acceptableValues to validate the value against a 
     * list of acceptable values 
     */ 

     return isValid; 
    } 

}; 

private ErrorCode errorCode; 

private ObjectValidation(ErrorCode ErrorCode) { 
    this.errorCode = ErrorCode; 
} 

public ErrorCode getErrorCode() { 
    return errorCode; 
} 

abstract boolean validate(String value, List<String> acceptableValues); 

}

A metoda usługa wykorzystać funkcjonalność sprawdzania stałego dostarczonego przez wyliczenia i mogą być wykorzystywane do wielu walidacji tego samego pola:

public static List<ErrorCode> validate(String value, Set<ObjectValidation> objectValidators) throws Exception{ 
     List<ErrorCode> errorCodeList = new ArrayList<ErrorCode>();   
     for (ObjectValidation objectValidation : objectValidators) { 
      if(!objectValidation.validate(value, Collections.emptyList())){ 
       errorCodeList.add(objectValidation.getErrorCode()); 
      } 
     }    
    return errorCodeList;  
} 
Powiązane problemy