我有一个C++基类CAbstrInstruction和大量直接子类:
class CAbstrInstruction { /* ... */ };
class CSleepInstruction: public CAbstrInstruction { /* ... */ };
class CSetInstruction: public CAbstrInstruction { /* ... */ };
class CIfInstruction: public CAbstrInstruction { /* ... */ };
class CWhileInstruction: public CAbstrInstruction { /* ... */ };
// ...
还有一个CScriptWorker,它公开了一个公共(public)方法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))来调用正确的私有(private)方法。在那儿
有任何设计模式或语言构造可以简化这一过程吗?
澄清:我可以将专用执行方法do ...移至指令中
类。 execute方法将变成:
void execute (const CAbstrInstruction *pI) { pI->execute(); }
但是,那不是我想要的。为什么不? 关注点分离:CAbstrInstruction的实例仅是对要执行的操作的描述。它们组成了脚本的抽象语法树。这已经足够了。 CScriptWorker的关注点是实际执行指令中描述的内容。 CScriptWorker知道脚本在其中运行的上下文。CAbstrInstruction不应该知道这一点。
最佳答案
CAbstrInstruction
应该定义一个纯虚方法(在您的示例中为execute()
),您的子类应该重写并实现。
举个例子:
class CAbstrInstruction
{
/* ... */
virtual void execute() const = 0;
}
class CSleepInstruction
{
/* ... */
void execute() override const
{
/* your code here */
}
}
/* ... */
void CScriptWorker::execute (const CAbstrInstruction *pI)
{
pI->execute();
}