I'm designing a flexible Wizard system that presents a number of screens to complete a task. Some screens may need to be skipped based on answers to prompts on one or more previous screens.

The conditions to skip a given screen need to be editable by a non-technical user via a UI. Multiple conditions need only be combined with and.

I have an initial design in mind, but it feels inelegant. I wonder if there's a better way to approach this class of problem.

Initial Design


UI Mockup


The first column allows the user to select a question from a previous screen.

The second column allows the user to select an operator applicable to the type of question asked.

The third column allows the user to enter one or more values depending on the selected operator.

Object Model

public enum Operations { ... }
public class Condition
    int QuestionId { get; set; }
    Operations Operation { get; set; }
    List<object> Parameters { get; private set; }

List<Condition> pageSkipConditions;

Controller Logic

bool allConditionsTrue = pageSkipConditions.Count > 0;
foreach (Condition c in pageSkipConditions)
    allConditionsTrue &= Evaluate(previousAnswers, c);

// ...

private bool Evaluate(List<Answers> previousAnswers, Condition c)
    switch (c.Operation)
        case Operations.StartsWith:
            // logic for this operation
        // etc.

Well, there's a formal pattern from Fowler that describes what you're doing right here. I've used it to design wizards that had branches as well (though I remember his decsription/documentation of that pattern being much better).

That said, if you take a step back and really look at what you're describing... it looks remarkably like a state machine. Those are well documented in many many places but they come in different flavours through implementation details. Most notable of those:

  • central control ie. some class manages the state transition logic (this looks similar to what you've designed already)
  • distributed control ie. each state knows of the transitions that leave it, and calls a state change on the parent whose state they implement
  • Calling this problem a state machine is overly general. IMO - if the OP simply wants the functionality described, he doesn't need a full featured state machine, what he has is simple enough. Sure, a state machine can be fitted to this, but so can a rules engine, neither of which may be necessary based on this simple logic. Jul 12 '12 at 6:28

One improvement:

Simply have a method in Condition.evaluate(List<Answers> previous) and implement the logic there, since it should be invariant. Scratches the switch statement.

Another comment: You might want to consider allowing multiple conditions per question ID. in the current model you'll have trouble jumping to different questions based on criteria (i.e., jump to 34 if I enter <4, jump to 92 otherwise, etc). You might also want to consider having conditions be part of Question or some mediating object (QuestionConditions or what have you)

Otherwise looks good to me, writing wizards sucks, keep it at simple as possible.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.