Business logic validation patterns & advices

前端 未结 2 1578
旧时难觅i
旧时难觅i 2020-12-24 15:14

I have two layers of validation in my application. First is entity validation performed by bean validation API (e.g. required fields). The second level is business logic val

相关标签:
2条回答
  • 2020-12-24 15:46

    You can use the strategy pattern.

    Each condition can be modeled as a function that takes a post and a session and might return an error:

    Post -> PostContext -> Optional<String> 
    

    You could represent this with an interface:

    @FunctionalInterface
    public interface ValidationCondition {
    
        Optional<String> validate(final Post post, final Session session);
    }
    

    So for example:

    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 the owner of the post");
        }
    }
    

    You can then store every validation in a list:

    final List<ValidationCondition> conditions = new ArrayList<>();
    
    conditions.add(new CreatorValidation());
    conditions.add(new ScoreValidation());
    // etc.
    

    Using the list, validations can be applied in bulk:

    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());
        }
    }
    

    Using Java 8 lambdas, you could declare these inline:

    final ValidationCondition condition = (post, session) -> {
        // Custom logic
    });
    
    0 讨论(0)
  • 2020-12-24 15:46

    Strategy pattern is the solution in my opinion. I will give you a very simple example. Lets say we have two kinds of credit cards, Visa and Mastercard. The logic to perform payment operation is the same for both cards, but card number validation is different. So, by passing VisaStrategy object through a workflow does the same logic and operations as we would pass MastercardStrategy, except one thing - card number validation, which is done inside each defined Strategy class, so you do not have any "if else" stuff in your code at all. Each Strategy class is now responsible for one and only one type of card validation. If you look for flexible and easy to maintain code structure - use Strategy design pattern.

    0 讨论(0)
提交回复
热议问题