lundi 9 décembre 2019

Should I pass parameters or inject them to the place where they are needed?

I have two components in my app. Component 1 is a "model builder". It's feeded with data every few milliseconds and returns a complex model, which is passed to Component 2. Component 2 analyzes the model and makes decisions based on it. I'm not sure how I should provide the new state of the model to Component 2.

Solution 1: Pass the model to Component 2 and "update" all dependencies at the entry point of the component. For example a very deeply nested object of Component2 may have injected "holder" and "holder2". By updating the holders with new information right at top layer, those leaf objects will get the information. This approach really feels like I'm communicating via side effects where it can get difficult to find out where the changes come from.

 public class Component2 {

 SomeInformationHolder holder; //these holders are requested for information deep down the object graph
 SomeOtherInformationHolder holder2;
 Subcomponent1 sub1;
 Subcomponent2 sub2;

 @Inject
 public Component2(Subcomponent1 sub1,Subcomponent2 sub2, 
                     SomeInformationHolder holder,  SomeOtherInformationHolder holder2) {
    super();
    ...
    ...
 }

 public void analyzModel(TaModel taModel) {
    holder.update(taModel.getInformation());
    holder2.update(taModel.getSomeOtherInformation());
    sub1.analyze();
    sub2.analyze();
 }
}

Solution 2: I pass the entire model deep down Component2's object graph via method calls. THis makes it very clear where the new information come from. However I hate to pass all the information down, only because a deeply nested object requires it. This really pollutes my code:

 public class Component2 {

 Subcomponent1 sub1;
 Subcomponent2 sub2;

 @Inject
 public Component2(Subcomponent1 sub1,Subcomponent2 sub2) {
    super();
    ...
    ...
 }

 public void analyzModel(TaModel taModel) {
    this.sub1.analyze(taModel); //from hereon the "taModel" is passed down deeply where it will be used in some leafs of the object graph
    this.sub2.analyze(taModel);
 }
}

Are there any good reasons why I should prefer one solution over the other? Does any of the solutions heavily violate any design practices?

Aucun commentaire:

Enregistrer un commentaire