业务逻辑validation模式和建议

我的应用程序中有两层validation。 首先是由beanvalidationAPI执行的实体validation(例如必填字段)。 第二级是业务逻辑validation。 例如,用户有一个post。 用户可以删除post,只有他是这篇文章的创建者并且评分<50。所以我必须做这样的事情:

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

我不喜欢这种方式,因为这个条件被重用,我必须重复代码。 此外,如果条件数大于5,则读取和理解代码变得不真实。

此外,标准的Spring Validator将不会非常有用,因为我必须为不同的操作(例如删除和更新)为一个实体制作不同的validation

所以我正在寻找一种更聪明的方式(模式可能),如果有人能给我一个提示,我将非常感激。

预先感谢!

您可以使用策略模式 。

每个条件都可以建模为一个函数,它接收一个post和一个会话,并可能返回一个错误:

 Post -> PostContext -> Optional 

您可以使用界面表示:

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

例如:

 public class CreatorValidation implements ValidationCondition { public Optional 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"); } } 

然后,您可以将每个validation存储在列表中:

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

使用该列表,可以批量应用validation:

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

使用Java 8 lambdas,您可以声明这些内联:

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

在我看来,战略模式是解决方案。 我会举一个非常简单的例子。 假设我们有两种信用卡,Visa和万事达卡。 执行付款操作的逻辑对于两张卡都是相同的,但卡号validation是不同的。 所以,通过工作流程传递VisaStrategy对象,我们会传递与MastercardStrategy相同的逻辑和操作,除了一件事 – 卡号validation,这是在每个定义的策略类中完成的,所以你没有任何“if else”的东西你的代码。 每个策略类现在负责一种且仅一种类型的卡validation。 如果您寻求灵活且易于维护的代码结构 – 请使用策略设计模式。