Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Better design for initialization within constructor

Tags:

java

oop

I have a class that looks something like this which acts as factory for clients based on credentials retrieved from credentials service. It builds clients one time and returns that on every call.

public class ClientFactory {
   private CredentialService credentialService;
   private ClientA clientA; 

   public ClientFactory(CredentialService credentialService){
      this.credentialService = credentialService;
      //initialization in constructor
      this.clientA = buildClientA(credentialService.getCredentials());
   }

   public ClientA getClientA(){
       return clientA;
   }

   /** Build new ClientA using crendentials*/
   private ClientA buildClientA(String credentials){
     return new ClientA(credentials);
   } 
}

Issue that I see with this is line 2 in the constructor which basically start using dependency 'credentialService' to initialize other dependencies immediately. If some other developer moves around order of code in constructor, it will start failing. Other option is too change method getClientA() to this.

   public ClientA getClientA(){
      if(clientA == null) {
        this.clientA = buildClientA(credentialService.getCredentials());
      }
       return clientA;
   }

But it has thread safety issues. Is there a better way to design above class which avoids concerns I highlighted above?

Thanks

like image 642
RandomQuestion Avatar asked Jan 18 '26 22:01

RandomQuestion


2 Answers

Well,

this.clientA = buildClientA(credentialService.getCredentials()); relies on the parameter credentialService passed to the constructor, not on the member this.credentialService. Therefore, the order of the initializations doesn't matter.

BTW, just to be safe and avoid confustion, I wouldn't use the same name for the parameter of the constructor and the member.

like image 177
Eran Avatar answered Jan 20 '26 11:01

Eran


Just don't save off a reference to theCredentialService as an instance variable, and continue passing credentialService.getCredentials() to bulldClientA. You are already not using the instance variable credentialService.

like image 26
NESPowerGlove Avatar answered Jan 20 '26 12:01

NESPowerGlove