2

I have an application with which a user can initiate (fill out a form and click Run) a series of steps.

First step 1 must be executed and afterwards step 2. If step 2 was successful, execute step 3 otherwise execute step 4. Finally step 5 must be executed.

Each step has about 10 to 100 lines of code.

With which design pattern should I structure my code best in order to implement this logic? Is it the chain of responsibility pattern, template method pattern, or something else altogether?

Hank Tuff
  • 185
  • 5
  • 12
  • 1
    "chain of responsibility" is not usually used for what you describe here. But you can make it – T.S. Aug 08 '20 at 20:43
  • So then what pattern, if there is one, is best suited here? – Hank Tuff Aug 08 '20 at 20:45
  • 2
    do you use a pattern to develop or you develop to use a pattern? – T.S. Aug 08 '20 at 20:48
  • Keep it simple. If there is a fixed set of steps, each step can be a method and it can throw or otherwise propagate failure to the caller. – Aluan Haddad Aug 08 '20 at 21:04
  • Are all five steps executed at the click of the Run button? Or are you talking about some sort of workflow (or “wizard”) with several screens the user must click through? – John Wu Aug 08 '20 at 21:40
  • Click of a button. But should each step be a class or a method? – Hank Tuff Aug 10 '20 at 05:38

2 Answers2

11
  • If the steps in the execution of your code mean different states of the system, in which it reacts differently to incoming messages, then this can be implemented using a State pattern.

  • If you have or will have a hierarchy of classes, each of which performs the same set of steps, but with a slightly different implementation, then the Template pattern is suitable.

  • If it's just a flow of execution consisting of several function calls, then see Olivier’s answer.

alex_noname
  • 26,459
  • 5
  • 69
  • 86
3

A few method calls and an if-else-statement should do what you want.

Step1();
if (Step2()) {
    Step3();
} else {
    Step4();
}
Step5();

Just let Step2 return a Boolean to tell if it was successful. If step 2 returns some data, you can also return null or an empty collection if the operation was not successful instead.

public bool Step2()
{
    //do things
    return <whether successful>;
}

This is simple and easy to understand.

Of course these methods can be implemented in different services for a better separation of concerns. E.g.

_ui.ShowWaitCursor(); // Step 1.
var data = _fileService.GetData(); // Step 2.
if (data != null) { // Check success of step 2.
    _dbService.WriteData(data); // Step 3.
} else {
    _dbService.WriteDefaults(); // Step 4.
}
_ui.HideWaitCursor(); // Step 5.

See also: Dependency injection (Wikipedia). If you are looking for a better way to organize your code, this is worth looking at.

Olivier Jacot-Descombes
  • 104,806
  • 13
  • 138
  • 188