0

I'm developing a complex desktop client with C#, which is mainly for some scientific analysis work. The class hierarchy of my project is very complicated. The problem is that, a large amount of parameters should be able to be modified by the user at the entrance of the client.

However, many parameters are very deep in the class hierarchy (I mean the composition hierarchy, not inheritance). As a result, classes closed to the top levels must take a lot of arguments in the constructor, because they are passed all the way up from different classes at the bottom levels.

What's the best practices to handle problems like this? I have 3 ideas:

  1. Global static variables: Just create a Constants class and store these params as static fields, like Constants.FOO, Constants.BAR.

  2. Singleton class: Create a singleton class, and initialize it at the entrance of program. Get these params like Constants.GetInstance().FOO.

  3. For every class, receive lower-level params in the constructor, which makes the constructor signature verbose and complicated. For example, a mid-level frequently-used class may take 15 arguments in the constructor.

If I use global variables or a singleton too often, the code will become very coupled. But if I do not use them, lots of params must be passed and received along the class hierarchy again and again. So how would a complicated commercial software do to solve this problem?


For example, the program creates a LevelOne object at the topmost level. The LevelOne contains fields like LevelTwoA and LevelTwoB. And a LevelTwoA object contains fields like LevelThree and so on. Then if the user wants to specify the value of a LevelTen field when creating the LevelOne, the value of LevelTen must be passed from the constructor of LevelOne to LevelNine.

And take a Car as an example, what if the user want to specify the Radius of a certian Gear when creating a Car? The Gear object must be at the bottom level of the whole hierarchy. However, a Car should not take a double radiusOfACertianGear as an argument in its constructor, because it's too trivial.

ProtossShuttle
  • 1,623
  • 20
  • 40
  • 1
    "As a result, classes closed to the top levels must take a lot of arguments in the constructor, because they are passed all the way up from different classes at the bottom levels" Sounds like the basic design needs a review. Current approach does not sound SOLID and violates the Law of Demeter. – dbugger Apr 07 '16 at 15:32
  • If you want less dependencies then you should follow @dbugger suggestion, and than you can consider using a Dependency Injection framework that could manage objects activations. What I would do is to convert multiple parameters into POCOs, which could simply be injected into your classes constructors (then singletons or not becomes just a performance choice). – Federico Dipuma Apr 07 '16 at 15:59
  • This answer made it click for me [Getting a set of dependencies to a class deeply nested in the dependency graph](http://stackoverflow.com/questions/9295312/getting-a-set-of-dependencies-to-a-class-deeply-nested-in-the-dependency-graph/9295632#9295632). Everything is created up front (keep your constructors light). And with an IOC framework your declaration is greatly simplified, as you don't need to manually register the classes it can figure out. Just make sure the first class to be created takes in its dependencies as arguments too. For things you need to create on the fly, have factories. – Tone Apr 08 '16 at 05:16

2 Answers2

1

Thanks for all comments and answers for my question. Dependency injection is exactly the solution. I have spend one afternoon learning how dependency injection works. A class should not produce other classes(dependencies) in there constructor, it should receive one from the argument instead.

And you also need one or more configuration files/classes to provide the values of all the parameters. Then create an injector/factory to create all needed objects/dependencies based on the configurations.

ProtossShuttle
  • 1,623
  • 20
  • 40
0

I would create a builder to construct the composing parts and fit them nicely together.

Glenner003
  • 1,450
  • 10
  • 20