views:

447

answers:

4

I am implementing a Wizard style user interface. As a user flows through the wizard, clicking next, depending on the choices they have chosen on each screen, the user will have to go through a certain set of wizard screens.

This is being built in ASP.NET MVC. I am wondering what design pattern would be best suited to implement the logic of the sequence of steps that are in the wizard. Again, they have multiple paths through the wizard depending on choices they make.

Could I use a linked list? The "Command Design Pattern"? What do you recommend?

To put it another way: Where/How do you abstract/encapsulate the logic of determining what is the next step in the wizard based on what the user has chosen on a particular step of the wizard?

+2  A: 

The "State" pattern might make sense, if you want to allow the user to navigate forwards and backwards through the wizard.

A workflow pattern might also make sense. Maybe investigate using Windows Workflow foundation.

Andy White
A: 

I have to agree with Beau.

Actually, if you need a complex set of rules for the navigation logic, then you have a wizard GUI-wise, but not a wizard under the hood.

If what are trying to build is really a wizard, each screen should flow into at most 2-3 different screens (IMO). That could be stored easily into a very simple structure (Database, static config file).

hoagie
But you have to define *some where* the sequence of the steps that make up the wizard. Because we need to be able to track what steps in the wizard the user has completed, so that we can display progress and other things. Or even so that they can come back to where they left off for example.
Roberto Sebestyen
+1  A: 

To put it another way: Where/How do you abstract/encapsulate the logic of determining what is the next step in the wizard based on what the user has chosen on a particular step of the wizard?

One way to do it would be to model Wizard, Step, and Product classes. Maybe something like this?

public class Wizard
{
  public Step forward() {//...}

  public Step backward() {//...}

  public Step current() {//...}

  public Product getProduct() {//...}
}

public class Step
{
  public String name() {//...}

  public void commit(Product product) {//...}

  public void rollback(Product product) {//...}
}

public class Product
{
  //...
}

The purpose of the Wizard is to build a Product (Car, Computer, Vacation, etc).

In this scenario, it's Wizard that decides the next step - perhaps based on the state of the Product that the Wizard is building. Wizard would be acting like a Builder under the control of the UI, which would be the Director and tell Wizard when and in what direction to make a transition. It's up to Wizard to decide what the next step actually is. Multiple branchpoints could be supported, but that implementation would be hidden away inside Wizard.

Step would be be an instance of the Command Pattern with undo/redo capability.

Rich Apodaca
+1  A: 

I like to keep it simple. I set a value on the object I am building with a step number, so if I am building up an insurance policy I would have a property on the policy that indicates what step it is on. Then I have a single method that is the router and looks at the policy and determines where to send it next, you can build extra logic into the router to skip steps or you can put the logic in each step method and redirect back to the router method.

James Avery