我有一个派生子类继承的基本类,它包含所有派生类应该相同的基本函数:
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() { ... }
}
但这意味着在更改任何派生类中的函数时,我必须编辑我的基类以反映这些更改。
是否有专门针对此类问题的设计模式?我购买了许多关于设计模式的书籍,但我是在“按需”的基础上研究它们,所以我不知道是否有这样的模式我正在寻找。
答案 0 :(得分:4)
我认为您需要的模式是责任链或者策略与动态调用表相结合......
答案 1 :(得分:4)
您可能会发现阅读Chain of responsibility pattern并以这种方式重新考虑您的解决方案非常有用。
您也可以将'doRun'声明为受保护的方法,并在基本默认情况下调用它。
default:
doRun(input);
在派生类中定义doRun。
这就是所谓的Template Method pattern
答案 2 :(得分:1)
解决这个问题的正常方法是使用工厂。概括地说:
现在增加奖励积分:
现在,当需要新输入时,您只需派生一个新类并将其注册到工厂。对switch语句的需求消失了。
答案 3 :(得分:1)
但这意味着在改变时 任何派生类中的函数,I 必须编辑我的基类 反映这些变化。
为什么会这样?
我点评你的评论 - 如果你选择这种方法,你就会遇到这些问题。其他人已经发布了建议其他解决方案的答案 - 我会检查这些解决方案以确定它们是否对您有所帮助。
答案 4 :(得分:1)
如果您的选择器值只是小整数,我会用查找表替换case语句。 (在这种情况下的操作将需要编码为一个函数,因此您可以将函数指针放在表中)。然后继承的类只能向表中添加条目。 (我猜表必须是一个实例属性,它不能是静态的)。
科林
答案 5 :(得分: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个以上的级别(即子类增加甚至更多的情况),那么你需要一个动态的调度表。