Hello,
I have the following design decision to make - running into it for the second time, so I hope I'm not the only one...
I have various Command classes that represent some actions. Each Command class (there are many, say SleepCommand, RunCommand, MeasureCommand) has different parameters with default values and so on, but in the end each has a generate()
method that returns some packed representation.
Now, I also have a CommandSequence class that aggregates many commands in a list. It has its own generate() method that does some custom work, runs generate()
for all the commands in its list, adds stuff of its own and so on.
I have a doubt of how to create these command objects. There are several alternatives:
(1) Let the user create instances of the various Command objects and just call an add_command() method on CommandSequence
(2) Create a "factory method" in CommandSequence for each of the possible Commands. The factory methods accepts the Command's arguments and passes them to the Command constructor.
(3) Since method (2) duplicates code (the constructor initialization lists of the objects), I can just make all the factory methods accept *args, **kwargs
and pass them to the objects.
Now, approach (1) doesn't duplicate code, but exposes the plethora of Command classes to the user. As opposed to (2) the user code is more verbose:
# seq is a CommandSequence object
seq.add_command(SleepCommand(time='10 ms', wakeup_alarm=False))
as opposed to:
seq.sleep(time='10 ms', wakeup_alarm=False)
Since I'm building a kind of a DSL, user code shortness and clearness is very important to me. I can use method (3) to save on code duplication, but then where to place the documentation of the Command classes - in the factory methods or in the classes' constructors themseves.
Am I missing some obvious pattern here? How would you approach this?