Search code examples
c++oopdesign-patternsstrategy-pattern

Recursive Strategy Pattern


I am designing some classes for my project in C++ at the moment but I got a problem. I want to create a camera class which holds all the needed values (e.g. transformation matrices) but the function which renders the camera should be exchangeable. This sounds like a usual case for the strategy pattern. Thus I created an interface which defines the render-function and gave the the camera class a pointer to this interface. The problem is that the render function needs access to all the data in the camera class and therefore I gave this function a pointer to the camera class as a parameter. It looks like this:

#include "ICameraRender.h"

class Camera{
private:
    ICameraRender*      _cameraRender;

public:
    Camera();
    Camera(ICameraRender& cameraRender);
    ~Camera();

    void renderCamera(){  _cameraRender->render(this); }


    void setCameraRender(ICameraRender& cameraRender);
        /..../

};


class ICameraRender{
public:
    virtual ~ICameraRender(){

    }

    //Override me
    virtual void render(Camera* camera) = 0;
};

This doesn't seem to be an elegant solution due to the liability to an infity loop (calling camera->renderCamera() in the render-function in ICameraRender). Is there a better solution to this problem?

Regards

EDIT:

I came up with another solution. Since the function which operates on the camera's data, only needs access to the data I thought I could split up the camera class itself. A class called Camera and CameraModel. The last one holds all the needed data and the first one does operations on it. Therefore I just have to pass a pointer to CameraModel to my function:

class CameraModel{
private:
    /...data.../
public:
   /...setter and getter.../
};

class Camera{
private: 
    CameraModel*   _cameraModel;
    ICameraRender* _cameraRender;

public:
Camera();
    Camera(ICameraRender& cameraRender);
    ~Camera();

    void renderCamera(){  _cameraRender->render(_cameraModel); }

    void setCameraRender(ICameraRender& cameraRender);
        /..../
};

class ICameraRender{
public:
    virtual ~ICameraRender(){

    }

    //Override me
    virtual void render(CameraModel* cameraModel) = 0;
};

Now the render-function (which only calculates new values for the camera according to user input) does no longer have access to the renderCamera-function. What do you think about this solution?

Regards Stan


Solution

  • You're right, it does seem like a bad design. :)

    I don't see why a camera render needs access to a camera. I'm sure you can pass something else as parameter. The render doesn't need access to all the camera members, so you can just pass the ones it needs (and, if there's a lot of them, wrap them in a structure CameraConfig or something like that).

    If the different renders need different parameters, you can make a separate hierarchy with ICameraConfig.