Home > database >  Java: Avoid too many parameters in constructor
Java: Avoid too many parameters in constructor

Time:05-05

I have multiple service classes ServiceTest1, ServiceTest2, SeviceTest3

I have a factory class UserFactory, which creates a new User instance on every request

UserFactory has a method createUser() which gets called for every request

Currently, createUser looks something like this

public User createUser(){

   return new User(new ServiceTest1(), new ServiceTest2(), new SeviceTest3());
}
  1. These Service classes are stateless though, so I want to avoid creating a new instance on every request,

  2. There might be more Sevice classes in future, I want to avoid cluttering the constructor with too many parameters

What would be the good practice to fix this?

Is it good if I let these Service classes be singleton classes? and have a new class named ServiceFactory, which provides these singleton services

and then, I can just place the ServiceFactory instance in the constructor new User(ServiceFactoy.getInstance())

CodePudding user response:

How about creating private static final ServiceTest in User class ?

Since the Services are stateless, just put them in to User, so you won't have too many parameters even if you have a new Service. Also, you won't create Service instance on every request.

public class User {
  
    private static final ServiceTest1 serviceTest1 = new ServiceTest1();
    private static final ServiceTest2 serviceTest2 = new ServiceTest2();
    // ...  
}

CodePudding user response:

I like the idea with the ServiceFactory, but I would definitely not use a singleton. You could use an interface as parameter type. This interface can then be implemented by your UserFactory or a member of it.

Your classes can easily be tested with mocks. Whether a service is reused or not (may change in future), is up to the implementation of the interface:

public class UserFactory { 
  ...
  public UserFactory(ServiceRegistry registry) {
    this.registry = registry;

  public User createUser() { 
    return new User(registry);
  }
  ...
}

public interface ServiceRegistry {

  ServiceTest1 getServiceTest1()
  ...
}
  
  • Related