验证应该在3层Entity-Repository-Service应用程序中完成?

时间:2014-05-19 14:42:03

标签: java oop design-patterns single-responsibility-principle

我正在努力定义验证过程在应用程序的不同层中的位置? (我这里不是在谈论用户输入验证,我真的在谈论对象的一致性)。

一个简单的案例:

  • 具有字段Blog的{​​{1}}实体和方法
    List<Comment>
  • 我想检查boolean addComment(Comment comment)的{​​{1}}参数是否为comment,这将返回boolean addComment(Comment comment)

对我来说,可以在nullfalse图层中进行此类检查,以确保在任何图层都能保持一致。

但这似乎是多余的,有些东西告诉我只有一层应该具有这种责任感。

我会说堆栈中最高的一个,因此Service层应该进行此验证吗?但是当我编写单元测试时,在Entity层中再次进行检查是错误的。

1 个答案:

答案 0 :(得分:1)

我的建议是把这些放在&#34; public&#34;服务的接口。使用任何公开方法,您都无法对输入质量提供任何保证。

以下是推理:

  • 服务可能会为内部代码客户端提供功能
  • 同样通过控制器暴露给Web服务。
  • Dao的永远不会公开曝光,因此 永远不需要实体验证。但实际上,他们会暴露出来。如果你确保只有服务呼叫dao(并且只有相关服务调用适当的dao&#39; s)然后你意识到dao是错误的地方
  • 服务代表可以轻松验证的代码的逻辑阻塞点。

实施此逻辑的最简单方法是创建一个方面并将验证代码放在那里。

<aop:aspect ref="validator" order="3">
    <aop:before method="doValidation" pointcut="execution(public * com.mycompany.myapp.services.*.*(..))"/>"/>
</aop:aspect>

因此,此方面bean示例涵盖服务层中的所有公共方法。

@Aspect
public class ServiceValidator{

    private Validator validator;

    public ServiceValidator() {
    }

    public ServiceValidator(Validator validator) {
        this.validator = validator;
    }

    public void doValidation(JoinPoint jp){
        for( Object arg : jp.getArgs() ){
            if (arg != null) {
                // uses hibernate validator
                Set<ConstraintViolation<Object>> violations = validator.validate(arg);
                if( violations.size() > 0 ){
                    // do something
                }
            }
        }
    }
}