【发布时间】:2018-12-01 16:35:35
【问题描述】:
我有一个 C++ 基类 CAbstrInstruction 和大量的直接子类:
class CAbstrInstruction { /* ... */ };
class CSleepInstruction: public CAbstrInstruction { /* ... */ };
class CSetInstruction: public CAbstrInstruction { /* ... */ };
class CIfInstruction: public CAbstrInstruction { /* ... */ };
class CWhileInstruction: public CAbstrInstruction { /* ... */ };
// ...
还有一个 CScriptWorker 公开了一个公共方法 execute:
class CScriptWorker
{
public:
void execute (const CAbstrInstruction *pI);
private:
void doSleep (const CSleepInstruction *pI);
void doSet (const CSetInstruction *pI);
void doIf (const CIfInstruction *pI);
void doWhile (const CWhileInstruction *pI);
// ...
};
目前execute方法的实现是这样的:
void CScriptWorker::execute (const CAbstrInstruction *pI)
{
const CSleepInstruction *pSleep =
dynamic_cast<const CSleepInstruction *>(pI);
if (pSleep != NULL)
{
doSleep (*pSleep);
return;
}
const CSetInstruction *pSet =
dynamic_cast<const CSetInstruction *>(pI);
if (pSet != NULL)
{
doSet (*pSet);
return;
}
const CIfInstruction *pIf =
dynamic_cast<const CIfInstruction *>(pI);
if (pIf != NULL)
{
doIf (*pIf);
return;
}
const CWhileInstruction *pWhile =
dynamic_cast<const CWhileInstruction *>(pI);
if (pWhile != NULL)
{
doWhile (*pWhile);
return;
}
/* ... */
}
这非常笨拙,需要 O(log(n)) 才能调用正确的私有方法。有没有 是否有任何设计模式或语言结构可以简化这一点?
澄清:我可以将私有执行方法 do... 移动到指令中 类。执行方法将简单地变成:
void execute (const CAbstrInstruction *pI) { pI->execute(); }
但是,这不是我想要的。为什么不? 关注点分离:CAbstrInstruction 的实例只是对要做什么的描述。它们构成了脚本的抽象语法树。这已经足够令人担忧了。 CScriptWorker 关心的是实际执行指令所描述的内容。 CScriptWorker 知道脚本运行的上下文。CAbstrInstruction 不应该知道。
【问题讨论】:
-
看看访问者设计模式
-
你说得对,我认为这可能会解决问题。
-
你的
CAbstrInstruction什么也没提供,你所做的相当于投射void*。作为接口应该提供哪些指令? -
不确定你的意思。当然,我已经删除了类中的所有细节。
-
我的意思是,您没有使用任何有意义的继承/多态性功能,代码与转换
void*相同,这绝不是一个好兆头。CAbstrInstruction应该向用户保证什么?
标签: c++ inheritance design-patterns