首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >重构业务逻辑验证

重构业务逻辑验证
EN

Stack Overflow用户
提问于 2017-08-17 15:01:43
回答 3查看 908关注 0票数 0

我试图重构这段代码

代码语言:javascript
复制
private void validate(Customer customer) {

    List<String> errors = new ArrayList<>();

    if (customer == null) {
        errors.add("Customer must not be null");
    }

    if (customer != null && customer.getName() == null) {
        errors.add("Name must not be null");
    }

    if (customer != null && customer.getName().isEmpty()) {
        errors.add("Name must not be empty");
    }

    if (customer != null) {
        Customer customerFromDb = customerRepository.findByName(customer.getName());
        if (customerFromDb != null) {
            errors.add("Customer already present on db");
        }
    }

    if (!errors.isEmpty()) {
        throw new ValidationException(errors);
    }
}

我读过这篇文章业务逻辑验证模式和建议

我想为我的实体和实体的字段构建一个通用的验证器,我写了以下文章

代码语言:javascript
复制
private void validate(Customer customer) {

    List<ValidationRule> validationRules = new ArrayList<>();

    validationRules.add(new NotNullValidationRule(customer));
    validationRules.add(new NotNullValidationRule(customer, Customer::getName));
    validationRules.add(new NotEmptyValidationRule(customer, Customer::getName));
    validationRules.add(new NotExistValidationRule(customer -> customerRepository.findByName(customer.getName())));

    Validator.validate(validationRules);
}

和Validator类

代码语言:javascript
复制
public class Validator {

    public static void validate(List<ValidationRule> validationRules) {
        final List<String> errors = new ArrayList<>();
        for (final ValidationRule rule : validationRules) {
            final Optional<String> error = rule.validate();
            if (error.isPresent()) {
                errors.add(error.get());
            }
        }

        if (!errors.isEmpty()) {
            throw new ValidationException(errors);
        }
    }
}

但我不知道如何实现接口ValidationRule和其他类(NotNullValidationRule、NotEmptyValidationRule、NotExistValidationRule)

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2018-09-07 07:46:13

我找到了这个解决方案:

我创建了一个接口ValidationRule

代码语言:javascript
复制
import java.util.Optional;

public interface ValidationRule {
    Optional<ValidationError> validate();
}

以及一些实现这些行为的类。

代码语言:javascript
复制
public class NotNullValidationRule implements ValidationRule {

    private Object object;
    private String field;

    public NotNullValidationRule(Object object, String field) {
        this.object = object;
        if (field == null || field.isEmpty()) {
            throw new IllegalArgumentException("field must not be null or emtpy");
        }
        this.field = field;
    }

    @Override public Optional<ValidationError> validate() {

        if (object == null) {
            return Optional.empty();
        }

        try {
            Object value = new PropertyDescriptor(field, object.getClass()).getReadMethod().invoke(object);
            if (value == null) {
                ValidationError validationError = new ValidationError();
                validationError.setName(object.getClass().getSimpleName() + "." + field);
                validationError.setError("Field " + field + " is null");
                return Optional.of(validationError);
            }
        }
        catch (Exception e) {
            throw new IllegalStateException("error during retrieve of field value");
        }

        return Optional.empty();
    }
}

在另一个地方,我传递一个方法来调用:

代码语言:javascript
复制
package it.winetsolutions.winactitime.core.service.validation;

import java.beans.PropertyDescriptor;
import java.util.Optional;
import java.util.function.Function;

public class NotExistValidationRule implements ValidationRule {

    Object object;
    String field;
    Function<? super String, ? super Object> function;

    public NotExistValidationRule(Object object, String field, Function<? super String, ? super Object> function) {
        this.object = object;
        if (field == null || field.isEmpty() || function == null) {
            throw new IllegalArgumentException("field and function must not be null or emtpy");
        }
        this.field = field;
        this.function = function;
    }

    @Override public Optional<ValidationError> validate() {

        if (object == null) {
            return Optional.empty();
        }

        try {
            Object value = new PropertyDescriptor(field, object.getClass()).getReadMethod().invoke(object);
            Long id = (Long) new PropertyDescriptor("id", object.getClass()).getReadMethod().invoke(object);
            Object result = function.apply(value == null ? (String) value : ((String) value).trim());
            if (result != null &&
                !id.equals((Long) new PropertyDescriptor("id", result.getClass()).getReadMethod().invoke(result))) {
                ValidationError validationError = new ValidationError();
                validationError.setName(object.getClass().getSimpleName() + "." + field);
                validationError.setError("Element with " + field +": " + value + " already exists");
                return Optional.of(validationError);
            }
        }
        catch (Exception e) {
            throw new IllegalStateException("error during retrieve of field value");
        }

        return Optional.empty();
    }
}
票数 0
EN

Stack Overflow用户

发布于 2017-08-17 15:36:54

我会写这样的东西:

代码语言:javascript
复制
CommonValidations.notNull(errors, customer);
if (customer != null) {
    CommonValidations.notEmpty(errors, customer.getName());
}
customerCustomeBeanValidations.validName(errors, customer.getName());
customerCustomeBeanValidations.notExist(errors, customer.getName());
票数 0
EN

Stack Overflow用户

发布于 2017-08-17 16:00:15

在您引用的链接中,接受的答案建议使用策略设计模式,然后给出一个接口和实现的示例。在您的示例中,您将创建一个新的接口ValidationRule,至少有一个方法验证(),然后创建每个实现该接口的具体类(NotNullValidationRule、NotEmptyValidationRule、AlreadyExistValidationRule)。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/45738658

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档