【问题标题】:alternatives to switch-case开关盒的替代品
【发布时间】:2017-03-11 19:50:08
【问题描述】:

我想知道这种 switch-case 用法是否合适,或者还有其他替代方案(模式)吗?

以下是我的程序的一部分:

基础是我正在执行一系列操作

  1. 一般程序控制都是按照case的顺序一个一个的;

  2. 通常任何特定情况在第一次调用时都没有完成,我们必须等到 procX returns true。 (等待仪器响应或动作完成);

  3. 可以跳转到特定的case(更改采样代码中的StepCurrent)。

我发现这种switch-case 很难维护,尤其是通过将StepCurrent 更改为直接控制流。而且代码看起来很丑。

有没有更好的方法?

注意:虽然我使用的是 C#,但问题可能不限于它。

    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++;
        }

【问题讨论】:

  • 你可以使用状态模式。每个 proc 都在每个状态下使用。比你可以改变到下一个状态
  • 您可以创建一个字典,其中数字为键,函数委托为值。这会使代码更小。
  • 创建一个类似于 Action 的 Func 数组:stackoverflow.com/questions/23477823/…
  • 这看起来不错。不可避免的事情是,当某一天插入新的 proc 时,例如在 proc0 和 proc1 之间,我必须更新对以前的 proc1 的任何引用,现在是 proc2。 - 这种头痛可能是不可避免的。

标签: c# switch-statement controls sequence


【解决方案1】:

您可以使用 Dictionary<int,Func<bool>> ,这样您的圈复杂度会更低,请参见示例:

注意:我使用 Dictionary 来表明您可以使用任何类型作为键,例如带有名称的 stringenum

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

而不是这样使用:

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

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

        if( bRetSts )
            StepCurrent++;
    }

【讨论】:

  • 这看起来不错。不可避免的是,当某一天插入新的 proc 时,例如在 proc0 和 proc1 之间,我必须更新对以前 proc1 的任何引用,现在是 proc2。 - 这种头痛可能是不可避免的。
【解决方案2】:
bRetSts = (StepCurrent == 0)? proc0():
          (StepCurrent == 1)? proc1():
          (StepCurrent == 2)? proc2():
          (StepCurrent == 3)? proc3():
          false; // it could be more proper to throw an exception

或者,如果所有 procX 都具有相同的签名,则可能更合适:

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

【讨论】:

  • o.o,我也会这样做,kkkkk
【解决方案3】:

我认为这是使用责任链设计模式的绝佳机会。

这是我发现的更好的描述之一:https://sourcemaking.com/design_patterns/chain_of_responsibility 也是实现示例:http://www.tutorialspoint.com/design_pattern/chain_of_responsibility_pattern.htm

【讨论】:

  • 这是我的第二个想法。但是没有退路。所以链resp。在使用案例 2 后不会使用案例 1。如果可能的话,我会使用责任链。从问题上看不清楚。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-02-16
  • 1970-01-01
  • 2011-10-24
  • 1970-01-01
  • 1970-01-01
  • 2013-08-18
相关资源
最近更新 更多