I find myself doing this sort of thing from time to time, and I wonder if it's a design smell, or if there's a better design pattern I can use.
There's a process with a number of steps that is known at compile time, but is likely to change down the road. I capture the commonality in an abstract Step class, write a StepLister that returns a list of steps, one for each derived class of Step, and then a StepsRunner which calls StepLister, then iterates over the list and runs each step. Sometimes one step will depend on the result of a previous step, sometimes not.
Any suggestions?