Chengting
Chengting

Reputation: 355

alternatives to switch-case

I want to know if this kind of switch-case usage is appropriate, or there is any other alternatives (patterns)?

the following is part of my program:

the basics is I am doing a sequence of actions

  1. generally program control is following the sequence of case one by one;

  2. usually any specific case is not finished in its first call, we have to wait until the procX returns true. (waiting for instrument response or action completion);

  3. jump to a specific case is possible (changing StepCurrent in the sampling code).

I found this kind of switch-case is hard to maintain, especially by changing the StepCurrent to direct control flow. And code looks ugly.

is there any better method?

note: though I am using C#, the problem might not be limited to it.

    while (true)
        {
            if (sig_IsExit())
            {
                break;
            }

            Thread.Sleep(500);

            bRetSts = false;
            switch (StepCurrent) // nSeq)
            {
                case 0:
                     bRetSts = proc0();
                     break;

                case 1:

                     bRetSts = proc1();
                    break;
                case 2:
                     bRetSts = proc2();
                    break;

                case 3:
                     bRetSts = proc3();
                    break;

                case 4:
                   ...
            }

            if( bRetSts )
                StepCurrent++;
        }

Upvotes: 3

Views: 20151

Answers (3)

Joel R Michaliszen
Joel R Michaliszen

Reputation: 4222

You can use a Dictionary<int,Func<bool>> , with this you will have less cyclomatic complexity, see the example:

Note: i use Dictionary to show that you can use any type as key, for example a string with a name, or an enum.

Dictionary<int,Func<bool>> proc = new Dictionary<int,Func<bool>>
{
   {0, proc0},
   {1, proc1},
   {2, proc2},
   {3, proc3},
}

and than use like that:

  while (true)
    {
        if (sig_IsExit())
           break;
        Thread.Sleep(500);

        bRetSts = false;
        bRetSts = proc[StepCurrent]();

        if( bRetSts )
            StepCurrent++;
    }

Upvotes: 13

AlexD
AlexD

Reputation: 32566

bRetSts = (StepCurrent == 0)? proc0():
          (StepCurrent == 1)? proc1():
          (StepCurrent == 2)? proc2():
          (StepCurrent == 3)? proc3():
          false; // it could be more proper to throw an exception

or, perhaps more appropriate if all procX have the same signature:

var funcs = new Func<bool>[] { proc0, proc1, proc2, proc3 };
funcs[StepCurrent]();

Upvotes: 2

Filip
Filip

Reputation: 1864

I think this is perfect opportunity to use Chain of responsibility design pattern.

Here is one of the better descriptions I found: https://sourcemaking.com/design_patterns/chain_of_responsibility Also example of implementation: http://www.tutorialspoint.com/design_pattern/chain_of_responsibility_pattern.htm

Upvotes: 0

Related Questions