5

I'm writing a console application that goes through an algorithm with N number of steps. It is important that step N is correctly done before step N+1 is executed. Otherwise the program should stop working with an error message.

I can do this with nested if statements of course and use try-catch-finally (using a continue flag in finally to decided if the program should process). But I am looking for a better structured design pattern or approach to do this. Any recommendations?

disasterkid
  • 6,948
  • 25
  • 94
  • 179

6 Answers6

10

The Pipeline design pattern is precisely about this: carrying out a complex process in a strict sequence of steps. Google "pipeline design pattern" and you'll find plenty of resources.

This is a programming-oriented introductory article on MSDN, and this is a more theoretical post.

CesarGon
  • 15,099
  • 6
  • 57
  • 85
7

Chain of responsibility

http://www.codeproject.com/Articles/455228/Design-Patterns-3-of-3-Behavioral-Design-Patterns#Chain

or State pattern

http://www.codeproject.com/Articles/455228/Design-Patterns-3-of-3-Behavioral-Design-Patterns#State

may be the solutions of your problem.

For chain of responsibility pattern, when you detect error, you just need set the "error message (handling)" process as the next process in the chain.

For state pattern, you need to change the state to "Error" when encountering error, and handle all the errors in the error state.

Hopefully, that helps.

Tim Hong
  • 2,734
  • 20
  • 23
3

I have once created an process that was controlling an automation and I used an enumeration with all the steps

enum AutomationStep{Requested, Started, Waiting, Processing, Terminating};

Later I created a switch/case to process every step differently

switch (currentStep)
{
  case AutomationStep.Requested : InitializeProcess(); currentstep = AutomationStep.Started; break;
  case AutomationStep.Started : StartTheEngines(); currentstep = AutomationStep.Waiting; break;
  case AutomationStep.Waiting : //etc
   break;
   default:
}

You may later use a While to run every step

Menelaos Vergis
  • 3,715
  • 5
  • 30
  • 46
  • This is a nice answer, and often used in low-level code, I just wanted to add that this pattern is often used to implement state-machines – Lorenzo May 29 '21 at 14:19
1

You can use either:

  1. Chain Of Responsibility. OR
  2. Maintain a List of Processes and loop through them to process your task. OR
  3. Use Function composition and chain your functions. In java 8 you can achieve this using Java 8 functional interfaces.

One example from Java 8 APIs could be the use of a comparator interface.

Below is an example of chaining functions using function composition:

Comparator.comparing(name).thenComparing(age).

Click here for a detailed article on this.

Bikas Katwal
  • 1,895
  • 1
  • 21
  • 42
0

One pattern I like is to update the object's state as it progresses from one step to the next, to indicate where it is in the process.

Rather than process one object from beginning to end, I have each step of the algorithm select all of the objects at a given state, process them, and update their state to be ready for the next step.

I make each step of the process a transaction, so that an object has either fully progressed to the next step, or is rolled back to its prior state and is ready to go through this step again.

That way, if your program is interrupted in the middle, you can just start it back up, and all objects can pick up right where they left off in the process.

mbeckish
  • 10,485
  • 5
  • 30
  • 55
0

Use recursion and return or stop when you hit an incorrect step

public void Process(int n)
{
 if( n % 23 != 0 )return;
 Process(n+1);
}

Where n is going to be your working data set or current set item. It is up to you to determine a data structure to use for that. Also, the modulus check for 23 is to show when to break from the recursive checks.

Travis J
  • 81,153
  • 41
  • 202
  • 273
  • 1
    But its the algorithm that is in steps... i.e. Step 1: Determine if parameters are even. Step 2: Multiply the parameters by 3. Step 3: Add parameters... So the recursion doesn't work here, because it's the steps that change. – neeKo Oct 31 '13 at 14:42
  • @NikoDrašković - One way would be to store the steps in actions and then use an int action dictionary. That would be the "data structure" aspect. – Travis J Oct 31 '13 at 14:51
  • If you had an action collection, you'd just do a foreach. Recursion makes no sense. The recursion you've written is essentially a `for(int n = 0; n < 23; n++) { .. }` with completely unnecessary overhead. – neeKo Oct 31 '13 at 14:57
  • @Niko - A foreach or a simple for loop will not be able to send information to the next step aside from an iterator. The `int` is just an example. Sorry you cannot visualize passing anything aside from an int. – Travis J Oct 31 '13 at 15:03
  • I can, but if you're always passing on a same kind of a data structure, you could have just stored it in between steps in the iteration. – neeKo Oct 31 '13 at 15:13
  • @Niko - But where is the fun in that? I think this question is a little too vague to be able to properly address. As a result, we could spend all day postulating multiple ways to do the same thing. – Travis J Oct 31 '13 at 15:19