Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Business logic validation patterns & advices

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 validation. For example, user has a post. User can delete a post only if he is a creator of this post and post rating < 50. So I have to do something like this:

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")

I don't like this way as this conditionals are reused and I have to duplicate code. Moreover, if number of conditionals is greater than 5 or so it becomes unreal to read and understand the code.

Moreover, standard Spring Validator won't be very helpful as I have to maker different validation for one entity on different actions (delete and update for example)

So I'm looking for a way to do this in a smarter way (pattern maybe) and I would be very grateful if someone could give me a hint.

Thank in advance!

like image 891
Rahul Avatar asked Jul 04 '16 12:07

Rahul


People also ask

What is Business logic validation?

Business logic tier validation assumes existing data is valid. The business logic tier employs validation logic when it needs to create or change data, but it assumes that data already in the table is valid.

What is a validator pattern?

The input validator pattern provides an architecture for securing an application from malicious input. Many common attacks, such as SQL injection, cross-site scripting, and buffer overflow attacks, are executed by providing an application malicious input.

What is logic validation?

About Validating Family Policy Logic Policy validation simulates policy execution, but no actions will be taken as a result (e.g., no Policy Recommendation records will be created). This prevents the policy from generating potentially invalid data while you are confirming that the policy logic is working as expected.

Which design pattern is implemented by validator class?

The chain of responsibility pattern is one of the most useful design patterns available to us in software engineering. It is also one of the most rarely implemented, in my experience at least.


1 Answers

You can use the strategy pattern.

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

Post -> Session -> 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
});
like image 56
sdgfsdh Avatar answered Sep 22 '22 07:09

sdgfsdh