vendredi 22 juin 2018

Quickly determine subclass based on abstract class

I have a C++ base class CAbstrInstruction and a large number of direct subclasses:

class CAbstrInstruction { /* ... */ };

class CSleepInstruction: public CAbstrInstruction { /* ... */ };
class CSetInstruction: public CAbstrInstruction { /* ... */ };
class CIfInstruction: public CAbstrInstruction { /* ... */ };
class CWhileInstruction: public CAbstrInstruction { /* ... */ };
// ...

There is also a CScriptWorker that exposes a public method 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);
        // ...
};

The implementation of the execute method currently looks like this:

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

    /* ... */
}

This is very clumsy and takes O(log(n)) to invoke the correct private method. Is there any design pattern or language construct that simplifies this?

(Clarification: I could move the private execute methods do... into the instruction classes. The execute method would simply become:

    void execute (const CAbstrInstruction *pI) { pI->execute(); }

However, that's not what I want, since the instruction classes are supposed to be just the descriptions of the instructions while the implementation of the execute methods should be in the CScriptWorker.)

Aucun commentaire:

Enregistrer un commentaire