Search code examples
c++oopdesign-patternssolid-principles

OOP - sharing data between classes


I have a class which keeps data and exposes methods to access that data: GameInfoList. A data is created based on 3 interfaces: A, B, C. I have also 2 interfaces to get a particular data: D, E.

I need to share GameInfoList between two classes, here is my approach:

//fills GameInfoList based on interfaces called by the different clients.
class GameInfo: public A, public B, public C
{
public:
    GameInfo(GameInfoList&)
    //A,B,C impl
private:
    GameInfoList& gameInfoList; 
};

//reads GameInfoList and allow to get a particular info.
class GameInfoProvider: public D, public E
{
public:
    GameInfoProvider(const GameInfoProvider&)
    //D,E impl
private:
    const GameInfoList& gameInfoList; 
};

Is there any design pattern which refers to the above scenario ? What do you think about my approach ?

Edit GameInfoList, GameInfo and GameInfoProvider objects exists in a "Component" class so the lifecycle is clear. A communication between components is based on thrift.


Solution

  • This is the inversion of control pattern. The problem with it in C++ is that GameInfoList does not have clear ownership.

    If your code is well disciplined, it probably isn't a problem. But if your code has more than -- oh -- one programmer working on it, it's a bit fragile because shared ownership is implied, and the life cycle of GameInfoList is outside the control of both GameInfo and GameInfoProvider.

    To get around the "who all owns GameInfoList, anyway?" problem, you could use a std::shared_ptr<GameInfoList> and that way the ownership of the GameInfoList is very clear.

    //fills GameInfoList based on interfaces called by the different clients.
    class GameInfo: public A, public B, public C
    {
    public:
        GameInfo(std::shared_ptr<GameInfoList>)
        //A,B,C impl
    private:
        std::shared_ptr<GameInfoList> gameInfoList; 
    };
    
    //reads GameInfoList and allow to get a particular info.
    class GameInfoProvider: public D, public E
    {
    public:
        GameInfoProvider(std::shared_ptr<GameInfoList>)
        //D,E impl
    private:
        std::shared_ptr<GameInfoList> gameInfoList; 
    };
    

    Notice that GameInfoProvider lost the const-ness of its use of GameInfoList. That is an unfortunate casualty of trying to express the shared ownership as I have above.

    If you use std::shared_ptr<const GameInfoList>, that treats the GameInfoList as an immutable value object, but you'd have to have it expressed that way in the GameInfo as well.

    There are other downsides in C++ to having a reference member variable in an instance object. The std::shared_ptr helps with that as well.