I am developing an application trying to follow the advice of hexagonal architecture and clean architecture. Dividing the application into layers: infrastructure, application, and model. All this keeping an eye on my imported packages and that there are only dependencies with the framework in the infrastructure layer.
The doubt has come with the implementation in the models. Most of the time if you validate maximum sizes of strings or maximum values and numbers you can use constants and if the condition is not met in the constructor then an exception is thrown:
@Value
public class UserName {
String value;
public UserName(String value) {
validate(value);
this.value = value;
}
private void validate(String value) {
if (value.length() > 100) {
throw new IllegalArgumentException();
}
}
}
The problem is if I want to parameterize these maximum values of the validations or in a properties or database file, for example. The mechanism would be coupled to the way of loading that data that the application framework uses. When should it be validated?
Loading the value in the use case (application layer) through a property service. For example:
public class CreateUser() {
private PropertiesService propertiesService;
public User create(String nameValue) {
UserName userName = new UserName(nameValue, propertiesService.getMaxNameLegth());
//...
}
}
@Value
public class UserName {
String value;
public UserName(String value, int maxValue) {
validate(value);
this.value = value;
}
private void validate(String value) {
if (value.length() > maxValue) {
throw new IllegalArgumentException();
}
}
}
Or creating a validator to which the class is passed and all its attributes are validated:
@Value
public class UserName {
String value;
public UserName(String value, int maxValue) {
this.value = value;
}
}
public interface UserNameValidator {
void validate(UserName userName);
}
public class UserNameValidatorImpl {
private PropertiesService propertiesService;
public void validate(UserName userName); {
if (userName.getValue().length() > propertiesService.getMaxNameLegth()) {
throw new IllegalArgumentException();
}
// validate all atributes
}
}
public class CreateUser() {
private UserNameValidator userNameValidator;
public User create(String nameValue) {
UserName userName = new UserName(nameValue);
userNameValidator.validate(userName);
//...
}
}
What is the best solution? the cleanest? Other better possibilities? Thanks.