I am working on a command-line application that runs simulations. It has to be heavily configurable; the user should be able to provide a very large number (100+) of parameters, some mandatory and some optional. Obviously, these parameters will be used by a variety of classes in the application.
I can see two approaches I can use; which one is a better design in the long run?
Approach 1
Have the (text) input file directly control object creation in the application. For example, user would provide the following input:
root=Simulation time=50 local_species=Sentient strength=3.5 intelligence=7.1 invading_species=Primitive strength=5.1 sociability=2.6
The application would then recursively create objects of the class specified on the rhs of the equal sign, passing the class' constructor the arguments provided in the relevant sub-branch of the input file, if any. I'm using Python, which supports keyword arguments and default argument values when no argument is provided, but I hope the question isn't terribly language-specific.
For example line 1 would tell the app to create an object of class Simulation
, with three constructor arguments. The first constructor argument is time=50
. The second argument is an instance of class Sentient
, which is created by passing Simulation
's constructor arguments strength=3.5
, intelligence=7.1
. The third argument is an instance of class Primitive
, which is created with by passing the constructor arguments strength=5.1
, sociability=2.6
.
The whole object creation is handled automatically, with just a few lines of (recursive) code. The highest-level object (instance of Simulation
in this case) would be passed to the visualization layer.
Approach 2
The input file still looks the same. However, the application's classes now have full control over how they interpret user input. The lhs and rhs values may or may not correspond to keyword parameters and classes. For example, the above input may result in the application creating an instance of class InvasionSimulation
with arguments strength_local=3.5
, intelligence_local=7.1
, strength_invading=5.1
, sociability_invading=2.6
, and then calling its method set_runtime(time=50)
, before passing the object to the visualization layer.
One obvious advantage of approach 2 is that the user's input can remain stable even as the application is completely redesigned internally. But I think there's nothing wrong with designating a subset of classes as "public API", and therefore ensuring that it doesn't change in the future, is there?
On the other hand, if the application internally follows something quite similar to approach 1 anyway, it feels that approach 2 requires adding a lot of redundant code: instead of automatically interpreting user input, we now need to do it "by hand" for each class.
Any additional considerations would be much appreciated. Are there any names for these approaches that I can search for?