如何在Java应用程序中简化具有多种实现的泛型接口的依赖注入?

问题描述 投票:0回答:1

我的界面如下所示:

public interface InputsValidator<T> {
    List<MessageEnum> validator(T input);
}

我有多种实现,例如:

@Component
class AddressInputsValidator implements InputsValidator<Address> {

    @Override
    public List<MessageEnum> validator(Address input) {
        List<MessageEnum> messages = new ArrayList<>();
        // Some actions
        return messages;
    }
}

@Component
class ContactInputsValidator implements InputsValidator<Contact> {

    @Override
    public List<MessageEnum> validator(Contact input) {
        List<MessageEnum> messages = new ArrayList<>();
        // Some actions
        return messages;
    }
}

现在,在我的 Spring Boot 服务中,我需要调用多个验证器。今天,如果我需要 10 个验证者,我需要声明所有验证者:

@Component
@RequiredArgsConstructor
class MyServiceApiImpl extends DelegateHelper implements UserApiDelegate {

    private final InputsValidator<Address> addressInputsValidator;
    private final InputsValidator<Contact> contactInputsValidator;
    ....
}

是否有一种优雅的方法或设计模式来替换每种类型的所有这些 InputsValidator 声明,而仅使用通用声明?例如

@Component
@RequiredArgsConstructor
class MyServiceApiImpl extends DelegateHelper implements UserApiDelegate {

    private final InputsValidator<T> inputsValidator; // Wrong solution
    ....
}
java generics design-patterns interface
1个回答
0
投票

我不确定我是否完全理解你的问题,但这里有一些想法。

您可以使用这样的类将同一类型的多个验证器分组:

public class MultiInputsValidator<T> implements InputsValidator<T> {
    private final InputsValidator<T>[] validators;

    public MultiInputsValidator(InputsValidator<T>... validators) {
        this.validators = validators;
    }

    @Override
    public List<MessageEnum> validator(T input) {
        List<MessageEnum> result = new ArrayList<>();
        for (InputsValidator<T> tor: validators) {
            result.addAll(tor.validator(input));
        }
        return result;
    }
}

您可以编写一个验证器类来验证对象的属性,如下所示:

public class PropertyValidator<T,F> implements InputsValidator<T> {
    private final Function<T,F> getter;
    private final InputsValidator<F> fieldValidator;

    public PropertyValidator(
            Function<T,F> getter, InputsValidator<F> fieldValidator) {
        this.getter = getter;
        this.fieldValidator = fieldValidator;
    }

    @Override
    public List<MessageEnum> validator(T input) {
        return fieldValidator.validator(getter.apply(input));
    }
}

您可以将上述内容组合到特定的课程中,例如:

public class Compound {
    private Contact contact;
    private Address address;

    public Contact getContact() {
        return contact;
    }

    public Address getAddress() {
        return address;
    }

    ...
}

如下:

@Component
public class CompoundInputsValidator extends MultiInputsValidator<Compound> {
    @Autowired
    public CompoundInputsValidator(
            AddressInputsValidator addressValidator,
            ContactInputsValidator contactValidator) {
        super(new PropertyValidator<>(Compound::getAddress,addressValidator),
                new PropertyValidator<>(Compound::getContact,contactValidator));
    }
    
}

我希望这会有所帮助。

© www.soinside.com 2019 - 2024. All rights reserved.