0

我有一个派生子类继承自的基本类,它具有在所有派生类中应该相同的基本功能:

class Basic {
public:
    Run() {
        int input = something->getsomething();
        switch(input)
        {
            /* Basic functionality */
            case 1:
                doA();
                break;
            case 2:
                doB();
                break;
            case 5:
                Foo();
                break;
        }
    }
};

现在,基于派生类,我想向 switch 中“添加”更多 case 语句。我在这里有什么选择?我可以声明虚函数,并且只在要使用它们的派生类中定义它们:

class Basic {
protected:
    virtual void DoSomethingElse();
public:
    Run() {
        int input = something->getsomething();
        switch(input)
        {
            /* Basic functionality */
            ...

            case 6:
                DoSomethingElse();
        }
    }
};


class Derived : public Basic {
protected:
    void DoSomethingElse() { ... }
}

但这意味着当更改任何派生类中的函数时,我必须编辑我的基类以反映这些更改。

是否有专门针对此类问题的设计模式?我购买了许多关于设计模式的书籍,但我正在“按需”研究它们,所以我不知道是否有我正在寻找的这种模式。

4

6 回答 6

4

我认为您需要的模式是责任链策略与动态调用表相结合......

于 2009-05-21T09:29:12.863 回答
4

您可能会发现阅读责任链模式并以这种方式重新考虑您的解决方案很有用。

您也可以将“doRun”声明为受保护方法并在基本默认情况下调用它。

default:
   doRun(input);

并在派生类中定义 doRun 。

这就是所谓的模板方法模式

于 2009-05-21T09:35:17.187 回答
1

处理这个问题的正常方法是使用工厂。概述:

  • 创建提供功能的相关类的层次结构。
  • 创建一个工厂类,该类接受输入并根据输入创建正确的类的实例

现在获得额外的奖励积分:

  • 创建一个在工厂中重新注册类的方案 - 您需要指定输入和类的类型来处理它

现在,当需要新输入时,您只需派生一个新类并将其注册到工厂。不再需要 switch 语句。

于 2009-05-21T09:28:47.590 回答
1

但这意味着当更改任何派生类中的函数时,我必须编辑我的基类以反映这些更改。

为什么这是真的?

我注意到您的评论 - 如果您选择这种方法,您将遇到这些问题。其他人已经发布了建议其他解决方案的答案 - 我会检查这些以查看它们是否对您有帮助。

于 2009-05-21T09:29:38.900 回答
1

如果您的选择器值只是小整数,我会用查找表替换 case 语句。(案例中的每个动作都需要编码为一个函数,因此您可以将函数指针放在表中)。然后继承的类可以只向表中添加条目。(我猜该表必须是一个实例属性,它不能是静态的)。

科林

于 2009-05-21T09:38:12.127 回答
1

А 简单的解决方案:

class Basic {
  public:
    void Run() {
      const int input = ...
      if (!(BaseProcess(input) || Process(input))) ...
    }

    vitual bool Process(int input) { return false; }

    bool BaseProcess(int input) {
      switch(input) {
    ...
        default: return false;
      }
      return true;
    }
...

...然后在子类的 Process() 中实现其他案例。如果您需要支持超过 2 个级别(即添加更多案例的子类),那么您将需要一个动态调度表。

于 2009-05-21T09:48:11.827 回答