多开关箱设计模式

Multiple switch cases design pattern

本文关键字:设计模式 开关箱      更新时间:2023-10-16

我有多个开关语句

switch(condition1)
{
 case 1:
  doSomething;
  break;
 case 2: 
  doSomething;
  break;
 default
  break;
}

--

 switch(condition2)
 {
  case 1:
   doSomething;
   break;
 case 2: 
  doSomething;
  break;
 default
  break;
 }

条件在未来可能会增加,例如条件3、条件4,即可能会有更多的切换语句。所以我需要可扩展性。

我想合并这些switch语句。我不想使用太多if,else条件。中间没有回流定子来中断流动。没有动态内存分配。没有多维数组。

例如。

result = someOperation(condition1, condition2, condition3...)
switch(result)
{
  case 1:
   doSomething;
   break;
 case 2: 
  doSomething;
  break;
 default
  break;
}

具体来说,我想生成多个int的唯一组合。不希望进行字符串比较。我更喜欢在一些设计模式中隐藏整个功能(尽管我找不到)

条件在未来可能会增加,例如条件3、条件4,即可能会有更多的切换语句。所以我需要可扩展性。

[评论:]策略模式会起作用,但我将如何选择该选择哪种策略。

考虑一下:

class operation // strategy base
{
public:
    virtual bool applies(int result) const = 0;
    virtual void perform() = 0;
    virtual ~operation() = 0;
};
class first_case: public operation // choose better name than first_case
{
public:
    bool applies(int result) const override
    {
        return result == 1; // equivalent of "case 1:"
    }
};
// other cases defined here

客户代码:

void do_stuff()
{
    // std::vector<std::unique_ptr<operation>> operations; defined else-where
    auto result = someOperation(condition1, condition2, condition3...);
    for(auto &op: operations) // equivalent of your switch above
        if(op.applies(result))
        {
            op.perform();
            break;
        }
}

基本上,您将策略选择标准实现为操作库上的虚拟API(并为每个操作专门化它)。

如果您需要一些可扩展的东西,也许您可以实现某种按条件结果索引的表,它存储指向代表条件结果调用的函数的指针。通过这种方式,您将获得可扩展的(您可以在运行时动态修改表)和高效的(嗯,不如switch语句高效,但可能足以满足您的目的)

如果您必须为条件添加新代码(或者最后一段的解决方案不够有效),最有效的方法是编写一个小程序,为您生成switch语句(也许在适当的位置生成#include语句),并将此生成包含在自动构建过程中。