Run time polymorphism to create a dynamic object with changing methods in it

  c++, c++11, design-patterns

This is a design suggestion question. Came up with something that uses bridge pattern. This will separate the type of accounts and the various operations on it. Below is the code for CAccounts class and it’s derived ones.

class CAccounts
{
public:
    virtual void create() = 0;
    virtual void activate() = 0;
    virtual void process() = 0;
    virtual void close() = 0;
};

class CPersonal : public CAccounts {
    shared_ptr< CAccountImplementation> implPtr;

public:
    CPersonal(shared_ptr< CAccountImplementation> impl) : implPtr(impl) {}
    virtual ~CPersonal();

    void create() {
        implPtr->create();
    }

    void activate() {
        implPtr->activate();
    }

    void process() {
        implPtr->process();
    }

    void close() {
        implPtr->close();
    }
};

class CBusiness : public CAccounts {
    shared_ptr< CAccountImplementation> implPtr;

public:
    CBusiness(shared_ptr< CAccountImplementation> impl) : implPtr(impl) {}
    virtual ~CBusiness();

    void create() {
        implPtr->create();
    }

    void activate() {
        implPtr->activate();
    }

    void process() {
        implPtr->process();
    }

    void close() {
        implPtr->close();
    }
};

class CFamily : public CAccounts {
    shared_ptr< CAccountImplementation> implPtr;

public:
    CFamily(shared_ptr< CAccountImplementation> impl) : implPtr(impl) {}
    virtual ~CFamily();

    void create() {
        implPtr->create();
    }

    void activate() {
        implPtr->activate();
    }

    void process() {
        implPtr->process();
    }

    void close() {
        implPtr->close();
    }
};

class CCombo : public CAccounts {
    shared_ptr< CAccountImplementation> implPtr;

public:
    CCombo(shared_ptr< CAccountImplementation> impl) : implPtr(impl) {}
    virtual ~CCombo();

    void create() {
        implPtr->create();
    }

    void activate() {
        implPtr->activate();
    }

    void process() {
        implPtr->process();
    }

    void close() {
        implPtr->close();
    }
};

CAccounts class is an interface class and bunch of other classes based on the account types are derived from it.
Now the implementation of account activities are in another set of implementation classes as shown below.

class CAccountImplementation
{
public:
    virtual void create() = 0;
    virtual void activate() = 0;
    virtual void process() = 0;
    virtual void close() = 0;
};

class CStockImplementation : public CAccountImplementation {
public:
    void create() {
        //Do Something
        //.......
        //.......
    }

    void activate() {
        //Do Something
        //.......
        //.......
    }

    void process() {
        //Do Something
        //.......
        //.......
    }

    void close() {
        //Do Something
        //.......
        //.......
    }
};

class CSharesImplementation : public CAccountImplementation {
public:
    void create() {
        //Do Something
        //.......
        //.......
    }

    void activate() {
        //Do Something
        //.......
        //.......
    }

    void process() {
        //Do Something
        //.......
        //.......
    }

    void close() {
        //Do Something
        //.......
        //.......
    }
};

class CBondsImplementation : public CAccountImplementation {
public:
    void create() {
        //Do Something
        //.......
        //.......
    }

    void activate() {
        //Do Something
        //.......
        //.......
    }

    void process() {
        //Do Something
        //.......
        //.......
    }

    void close() {
        //Do Something
        //.......
        //.......
    }
};

Now in main() it can be called as below. This is for a stock implementation for personal account.

shared_ptr<CAccountImplementation> implPtr = static_pointer_cast<CAccountImplementation>(make_shared<CStockImplementation>());
    shared_ptr<CAccounts> acctPtr = static_pointer_cast<CAccounts>(make_shared<CPersonal>(implPtr));
    acctPtr->create();

This design works as long as any of the accounts class only need to use any of the one implementation class.

i.e., for e.g., CBusiness can use the CBondImplementation.

Now if an account like CCombo wants to use different combinations of implementation methods, then this design will not work.

i.e., for e.g., CCombo wants to use create() in CStockImplementation and then process() in CShareImplementation and close() in CBondImplementation, then this design has it’s limitations. Can create separate objects of these other implementation classes and use it.

But need something different. i.e., one implementation class where it’s possible to inject various different methods and then use that implementation pointer.

Ideally this should be happening in runtime. Something like below,

class CMotherOfAllImplementations {
       CMotherOfAllImplementations (/*pass varient number of APIs*/) 
       { /* Do Something to initialize those APIs*/}
};

Above is something that may or may not be possible. It’ll be great to get some good design strategy and some sample code.

Source: Windows Questions C++

LEAVE A COMMENT