2009-05-21 77 views
1

我有一个派生的子类继承基本类,它承载的是应该是相同的所有派生类的基本功能:可选功能的设计模式?

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

现在的基础上,派生类,我想“添加”更多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

您可能会发现阅读Chain of responsibility pattern有用,并以此方式重新考虑您的解决方案。

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

default: 
    doRun(input); 

并在派生类中定义doRun。

这就是所谓的Template Method pattern

+0

我想我现在要去模板方法模式。我一定会阅读并考虑在这里列出的其他模式,但现在这可以被标记为接受:) – 2009-05-21 09:49:31

1

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

  • 创建提供功能的相关类的层次结构。
  • 创建一个工厂类,它的输入,并创建依赖于输入现在

的加分点类的权kindf的一个实例:

  • 创建reghisters类withn方案工厂 - 你需要指定输入和类的类型来处理它

现在,当需要一个新的输入时,你只需派生一个新的类并注册它与工厂。 switch语句的需要消失。

+0

我会试着澄清一下我的推理:我不需要根据输入派生:派生类不会生活在堆栈上。我只是想分离不同类型的逻辑,但仍然为所有派生类保留一些“基本”逻辑。 – 2009-05-21 09:55:35

4

我想你需要的模式是链责任中也许战略与动态调用表合并...

1

但在任何派生类中改变 功能时,这将意味着,我 将不得不编辑我的基类到 反映这些更改。

为什么会这样呢?

我点亮你的评论 - 然后如果你选择这种方法,你会有这些问题。其他人发布了可以提供其他解决方案的答案 - 我会检查这些答案,看看他们是否能够帮助你。

+0

嗯,或许我写得很差。当我更改函数的内容时,我不必这样做,但是当我删除一个函数或更改它的名称时,我将不得不返回到Basic类以反映这些更改。另外,我不想结束一个拥有大量虚拟功能的'基础'类;一个用于从它派生的任何类中的每个函数。 – 2009-05-21 09:34:26

+0

只有在Basic类需要虚函数的时候才会出现这种情况......任何一段代码是否会在Basic类对象上调用这些函数,或者它们只是在子类中用于私有用途? 如果每个对象的类的类型是已知的(也就是说,你不需要多态性,这似乎是这种情况),你不需要在基类中声明虚函数。 – fortran 2009-05-21 09:58:11

1

如果您选择值只是小的整数,我会通过查找表代替case语句。 (在这个例子中的动作都需要被编码为一个函数,所以你可以把函数指针放在表中)。然后,继承的类可以将条目添加到表中。 (我猜这个表必须是一个实例属性,它不能是静态的)。

科林

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

...,然后实现在子类的附加箱子处理()。 如果你需要支持2个以上的级别(即子类添加更多的情况),那么你需要一个动态调度表。