How come a finite state machine isn't a good fit? See the turnstile example in this wiki about finite-state machine.
Looking at the "state transition table" they have, you can easily think of the column headers as properties of an IQuestion
interface:
- Current State: The current
IQuestion
- Input:
IQuestion.Answer
. - Next State:
IQuestion.NextIQuestion
- Output: Whatever it does to your system.
What you get is a graph of IQuestion
s (which can be of various types: MultipleChoiceQuestion, DateQuestion, etc.) that have routing logic built in.
You seem to be worried about reuse/reordering of questions, which you can handle with some abstraction. Maybe make IQuestion
not care about the routing concerns, and just have properties like QuestionText
, PossibleAnswers
, etc, then have an IQuestionNode
that can store the actual graph/routing concerns. It could handle evaluating the IQuestion
and provide a pointer to the next question based on a fixed sequence or by inspecting the selected answer to the current question.
Then all you really need to do is define a State/Event table (see the wiki explanation for more on this) that can be transformed by your system into this graph.
You may also want to take a look at the Strategy Pattern for loading up different graphs of questionnaires based on different needs.