I have the following situation: I have a class (let's call it Main) encapsulating a complex process. This class in turn orchestrates a sequence of subalgorithms (AlgoA, AlgoB), each one represented by an individual class.

To configure Main, I have a configuration stored into a configuration object MainConfig. This object contains all the config information for AlgoA and AlgoB with their specific parameters. AlgoA has no interest to the information relative to the configuration of AlgoB, so technically I could have (and in practice I have) a contained MainConfig.AlgoAConfig and MainConfig.AlgoBConfig instances, and initialize as AlgoA(MainConfig.AlgoAConfig) and AlgoB(MainConfig.AlgoBConfig).

The problem is that there is some common configuration data. One example is the printLevel. I currently have MainConfig.printLevel. I need to propagate this information to both AlgoA and AlgoB, because they have to know how much to print. MainConfig also needs to know how much to print. So the solutions available are

I pass the MainConfig to AlgoA and AlgoB. This way, AlgoA has technically access to the whole configuration (even that of AlgoB) and is less self-contained

I copy the MainConfig.printLevel into AlgoAConfig and AlgoBConfig, so I basically have three printLevel information repeated.

I create a third configuration class PrintingConfig. I have an instance variable MainConfig.printingConfig, and then pass to AlgoA both MainConfig.AlgoAConfig and MainConfig.printingConfig.

Have you ever found this situation? How did you solve it ? Which one is stylistically clearer to a new reader of the code ?

1 Answer
1

I would say it's better to have multiple small classes with a single responsibility than one big god-configurator, even if that means you will have some duplication.

If the duplicate logic is complicated, (I'm assuming that printLevel was just an oversimplified example) then you can solve it with creating an object specifically for printLevel and packing it in the others.

In your example, this would mean

delete MainConfig completely and put the common printing configuration in a PrintConfig

aggregate the new class where it's needed, for ex AlgoAConfig.PrintConfig and AlgoBConfig.PrintConfig