2016-07-04 14 views
6

Mam dwie warstwy sprawdzania poprawności w mojej aplikacji. Pierwszym jest walidacja jednostki przeprowadzona przez API sprawdzania fasoli (na przykład wymagane pola). Drugi poziom to sprawdzanie logiki biznesowej. Na przykład użytkownik ma wpis. Użytkownik może usunąć post tylko wtedy, gdy jest on twórcą tego postu i po ocenie < 50. więc muszę zrobić coś takiego:Wzorce i porady dotyczące sprawdzania logiki biznesowej

if (post.getCreator().equals(session.getUser())) { 
    if (post.getRating() < 50) { 
    postRepository.delete(post); 
    } else errors.add(400, "Cant delete post with rating 50 or higher") 
} else errors add (400, "You should be owner of the post") 

Nie lubię w ten sposób, jak to warunkowe są ponownie wykorzystywane, a ja musisz skopiować kod. Co więcej, jeśli liczba warunków jest większa niż 5, odczytanie i zrozumienie kodu staje się nierzeczywiste.

Ponadto norma Wiosna Validator nie będzie bardzo pomocne jak mam ekspres do innego walidacji dla jednego podmiotu na różnych działań (usuwanie i aktualizowanie na przykład)

Więc szukam sposobu, aby to zrobić w mądrzejszy sposób (może wzór) i byłbym bardzo wdzięczny, gdyby ktoś mógł dać mi wskazówkę.

Z góry dziękuję!

Odpowiedz

5

Można użyć the strategy pattern.

Każdy stan może być modelowana jako funkcja, która zajmuje stanowisko i sesję i może zwróci błąd:

Post -> PostContext -> Optional<String> 

Można reprezentowania z interfejsem:

@FunctionalInterface 
public interface ValidationCondition { 

    Optional<String> validate(final Post post, final Session session); 
} 

Tak na przykład :

public class CreatorValidation implements ValidationCondition { 

    public Optional<String> validate(final Post post, final Session session) { 
     if (post.getCreator().equals(session.getUser()) { 
      return Optional.empty(); 
     } 
     return Optional.of("You should be owner of the post"); 
    } 
} 

Następnie można zapisać każdą weryfikację na liście:

final List<ValidationCondition> conditions = new ArrayList<>(); 

conditions.add(new CreatorValidation()); 
conditions.add(new ScoreValidation()); 
// etc. 

Korzystanie z listy, walidacji mogą być stosowane w dużych ilościach:

final List<String> errors = new ArrayList<>(); 

for (final ValidationCondition condition : conditions) { 
    final Optional<String> error = condition.validate(post, session); 
    if (error.isPresent()) { 
     errors.add(error.get()); 
    } 
} 

Korzystanie Java 8 lambdy, można zadeklarować te inline:

final ValidationCondition condition = (post, session) -> { 
    // Custom logic 
}); 
2

Strategia wzór jest rozwiązaniem w moim opinia. Dam wam bardzo prosty przykład. Powiedzmy, że mamy dwa rodzaje kart kredytowych, Visa i Mastercard. Logika wykonywania operacji płatniczych jest taka sama dla obu kart, ale walidacja numeru karty jest inna. Tak więc, przekazując obiekt VisaStrategy przez przepływ pracy, odbywa się ta sama logika i operacje, co przy przekazywaniu MastercardStrategy, z wyjątkiem jednej rzeczy - sprawdzania numeru karty, która odbywa się wewnątrz każdej zdefiniowanej klasy strategii, więc nie masz żadnych rzeczy "jeśli" Twój kod w ogóle. Każda klasa strategii jest teraz odpowiedzialna za jeden i tylko jeden rodzaj sprawdzania poprawności karty. Jeśli szukasz elastycznej i łatwej w utrzymaniu struktury kodu - użyj wzoru projektu strategii.

+0

Co się stanie, jeśli parametry metody sprawdzania różnią się w zależności od warunku? Powiedzmy, że numer karty Visa jest liczbą całkowitą i ma 4-cyfrowy kod, ale numer karty głównej to jeden 16-cyfrowy numer? – ahmet

Powiązane problemy