我的界面如下所示:
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
....
}
我不确定我是否完全理解你的问题,但这里有一些想法。
您可以使用这样的类将同一类型的多个验证器分组:
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));
}
}
我希望这会有所帮助。