samedi 18 mars 2023

Dependency injection how to avoid hiding dependencies to stateful objects like a validator

I would like to have your opinion about such a situation, the code is quite simple to should be easy to follow:

@Component
class MyService {
    
    AusiliaryService ausService;

    public MyService(AusiliaryService ausService) {
        ...
    }

    public boolean isAccountValid(Account account) {

     AccountValidator accountValidator = new AccountValidator(account);
     boolean isValid = accountValidator.isValid(account);
     if(isValid) {
        ausService.openAccount(account);
     }
    }
}

Note that AusiliaryService is also spring managed and we are using constructor injection.

In this class AccountValidator is a dependency of MyService but it does not appear in the constructor so we could say the visibility of this dependency is somehow hidden.

Since we are hardcoding the instantiation of
AccountValidator accountValidator = new AccountValidator(account);

We may also have some potential issues with writing unit tests MyService, unless you may think such any unit tests should also impact AccountValidator, which for me would be a valid line of thought.

A possible work around for both "issues" would be to use a factory, to remove from MyService the responsability to instantiate AccountValidator object.

@Component
class MyService {
    
    AusiliaryService ausService;
    AccountValidatorFactory accountValidatorFactory;

    public MyService(AusiliaryService ausService, AccountValidatorFactory accountValidatorFactory;) {
        ...
    }

    public boolean isAccountValid(Account account) {

     AccountValidator accountValidator = accountValidatorFactory.getValidator(account);
     boolean isValid = accountValidator.isValid(account);
     if(isValid) {
        ausService.openAccount(account);
     }
    }
}

Note that also AccountValidatorFactory is spring managed and we are using constructor injection.

A cons of this solution could be though the proliferation of such factories classes, if you use this kind of pattern often in your code.

What would is your approach in such situations ? Which kind of solution would you prefer ? Would be possible to make AccountValidator also spring managed to help with this, how would that be done ?

Aucun commentaire:

Enregistrer un commentaire