Wróciłem do zabawy z Vavrem i pisze sobie prostą klase odpowiedzialną za walidację jakiegoś obiektu.
@Component
public class QuestionValidator {
public Validation<Seq<Problem>, CreateQuestionCommand> validateCreateQuestionCommand(final CreateQuestionCommand command) {
return Validation.combine(
isNotBlank(command.getAnswer(), Problem.BLANK_ANSWER),
isNotBlank(command.getContent(), Problem.BLANK_CONTENT),
hasAtLeastOneElement(command.getTags())
).ap(CreateQuestionCommand::new);
}
private Validation<Problem, String> isNotBlank(final String value, final Problem problem) {
return value != null && !value.isBlank() ? Validation.valid(value) : Validation.invalid(problem);
}
private Validation<Problem, Set<String> > hasAtLeastOneElement(final Set<String> tags) {
return tags != null && !tags.isEmpty() ? Validation.valid(tags) : Validation.invalid(Problem.TOO_FEW_TAG);
}
}
No i ok, działa to tak jak chce. problem jest w tym, że chce dodac jedną regułę więcej, mianowicie - maksymalna liczba tagów to 5.
private Validation<Problem, Set<String> > hasNoMoreThanFiveElements(final Set<String> tags) {
return tags != null && tags.size() <= 5 ? Validation.valid(tags) : Validation.invalid(Problem.TOO_MANY_TAGS);
}
Tyle, że jak to dodam do środka metody combine, oznaczać będzie że wewnątrz metody ap() będe musiał podać Function4.
Czyli wyjściowy obiekt będzie musiał mieć 4 pola. Co jest czywiście bez sensu, z racji tego że 2x waliduje to samo pole, czyli tags, nie oznacza że chce je 2x trzymać w wyjściowym obiekcie.
Próbowałem też w ten sposób
private Validation<Seq<Problem>, Set<String>> hasValidNumberOfElements(final Set<String> tags) {
return Validation.combine(hasAtLeastOneElement(tags), hasNoMoreThanFiveElements(tags)).ap((i, j) -> new HashSet<>(i));
}
Metoda ap() znów wymaga dwóch parametrów, ale w tym przypadku dało się to rozwiązać w co prawda średnio elegancki sposób. Użycie jednak tego w metodzie combine o której mowa na początku jest jednak nie możliwe,
No i nie bardzo wiem jak wybrnąć... zaznaczę od razu, że zdaje sobie sprawę, że w tym konkrentym przypadku nie możliwe jest że wystąpią obydwa błędy walidacji (< 1 i > 5 elementów), jednak chyba każdy może sobie wyobrazić taki przypadek.
Edit#
Ok, zaćmienie umysłu.... mogę zrobić coś takiego
public Validation<Seq<Problem>, CreateQuestionCommand> validateCreateQuestionRequest(final CreateQuestionCommand command) {
return Validation.combine(
isNotBlank(command.getAnswer(), Problem.BLANK_ANSWER),
isNotBlank(command.getContent(), Problem.BLANK_CONTENT),
hasAtLeastOneElement(command.getTags()),
hasNoMoreThanFiveElements(command.getTags())
).ap((a, b, c, d) -> new CreateQuestionCommand(a, b, c));
}
Mimo wszystko, jakoś nie jestem do tego przekonany
- screenshot-20200910211927.png (21 KB) - ściągnięć: 4
- screenshot-20200910211020.png (12 KB) - ściągnięć: 8
- screenshot-20200910211133.png (26 KB) - ściągnięć: 3