1

This question already has an answer here:

I have many dataservices/classes injected into a constructor.

public MyClassConstructor (IAclass A, IBclass B, .... , IZclass Z){
    ...
}

The number I have to pass down goes well beyond 100. To solve this I created a Injected class that contains all the DataServices. Making it more streamlined:

public MyClassConstructor (IDataServices dataServices){...}

This works well, but is unfortunately an anti-pattern. When testing I need to manually instantiate all the classes even if just a single one is needed (for all functions). As an alternative I created Interfaces to be passed down for only classes that are needed.

public MyClassConstructor (IMainInterface mainInterface) {
    A = new A(mainInterface);
    B = new B(mainInterface);
}

public AClassContructor (IAInterface) {...}

public BClassContructor (IBInterface) {...}

This Resolves the previous two issues, but creates a new one where I am sitting with 100s of different Interface Classes.

Which one of these are is the best approach, and are there any more efficient/better ways to handle this problem?

marked as duplicate by Greg Burghardt, BobDalgleish, Community Jul 24 at 21:37

This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.

  • 1
    With that many dependencies, you should think if your class doesn't have too many responsibilities. Or maybe your overall design is not appropriate for problem you are trying to solve with your code. – Euphoric Jul 24 at 5:21
  • @Euphoric, unfortunately the responsibilities of the class can't be changed. What is is an reality is a APIController, we have many controllers, but a single one is meant to represent an Module/Standalone Application. They are devided as such and grouped according to name and security permissions. – Cornel Jul 24 at 21:41
2

The proper way to handle constructors with long parameter lists is to either break up the class so that it's dealing with fewer dependencies or group a few similar dependencies into one class with a name that makes clear what does and dosn't belong in it. Which you should do depends entirely on the abstractions this lets you build. If you can think of good names that ensure people wont be surprised by what they find inside then you have a good abstraction. If your class name is MyClassConstructor you don't.

Names are important. How we humans think is important. The computer doesn't care what you call it so name it to help the humans.

Since this is about humans one of the things you can do to make long parameter lists more tolerable is to use a language that allows named parameters. This helps because it's easy to forget the order the parameters are expected in.

If you're in a language without them (like Java) you can simulate them using the Joshua Block Builder Pattern

Using that, this:

NutritionFacts cocaCola = new NutritionFacts(240, 8, 100, 0, 35, 27);

Becomes this:

NutritionFacts cocaCola = new NutritionFacts
    .Builder(240, 8)
    .calories(100)
    .sodium(35)
    .carbohydrate(27)
    .build()
;

Which takes all the same information but is far more readable.

  • thank you for the response, but unfortunately it doesn't quite help me out. The fault is mine for not giving more information. Firstly, the classes I am passing down are simply dependency injected Data Services/Repositories into APIControllers. So I don't actually have a chance to instantiate them manually. Secondly, due to the nature of the controller and associated security privileges I can't reduce the responsibilities of each controller. (Each controlelr represents a standalone module) Lastly, the naming used in the question is simply for abstraction. Hope this helps. – Cornel Jul 24 at 21:56

Not the answer you're looking for? Browse other questions tagged or ask your own question.