0

I have the following question.

I have an abstract class that manages graphic elements. Let's call it GraphicHost. Something like that:

class GraphicHost {
    class GraphicHostState {
        List<Sprite> sprites;
        List<Text> texts;
    }

    GraphicHostState state;
    public void setState(GraphicHostState s);
    public GraphicHostState getState();

    public void addSprite(Sprite s);
    public void addText(Text t);    
}

I need to save and restore the state as I move from one scene to another, hence state subclass.

Now I have a concrete implementation that uses, say, OpenGL. Clearly, besides the basic state, I'll also need shaders' and textures' handles etc.

Will it be a good solution to inherit GraphicHostState and add them there? Like:

...
class GLGraphicHostState {
    List<Integer> textures;
    List<Integer> shaders;
}
...

The problem is that the graphic host object has to be polymorphic. I have ScriptHost that uses graphic host to add sprites/texts, and it shouldn't know about concrete implementation, but should be able to save and restore it's state. I can override getState/setState, but then in setState I'll have to check whether the supplied state is GLGraphicHostState, and this check seems a bit untidy, like a workaround.

So, generally, how would you suggest to do it if I have an abstract class with some state, child class with additional state parameter and the state has to be saved/restored in a polymorphic manner (via parent GraphicHost interface)?

As far as I understand Memento pattern suits the situation when state has to be saved and restored, but how do I fit it to class hierarchy like the aforementioned?

  • I find it's rather difficult to think about abstraction when I have no frame of reference. If you're writing a subclass of GraphicHost for OpenGL implementation, it's enough that it is a subclass for now until you need to implement others later. At that point, you can decide which information must be shared and what is entirely pertaining to OpenGL. In other words, don't fret too much about abstraction until you think you'll genuinely need it. – Neil Jul 3 '18 at 8:55
2

I feel that your entire approach is misguided here. As I know C# better than Java, I'll express the code using the former. But the some general ideas apply to other languages too.

Firstly, there's no real need for an abstract class here. So use an interface:

interface IGraphicHost 
{
    GraphicHostState State { get; set; }
    void addSprite(Sprite s);
    void addText(Text t);    
}

Next we need to deal with the problem that different implementations need different versions of GraphicHostState. I'd opt for one of two alternatives to deal with this:

Option 1: Use generics

interface IGraphicHost<TState> where TState : IGraphicHostState
{
    TState State { get; set; };
    public void addSprite(Sprite s);
    public void addText(Text t);    
}

So now each implementation of IGraphicHost then supplies it's own implementation of IGraphicHostState, eg:

class GLGraphicHost : IGraphicHost<GLGraphicHostState>
{
    ...
}

Option 2: Have the class handle it's own state saving and loading

interface IGraphicHost
{
    void SaveState(Stream stateStream);
    void RestoreState(Stream stateStream);

    public void addSprite(Sprite s);
    public void addText(Text t);    
}

So now, the class is supplied with a stream to which it can read and write its own state. What that state looks like, and how it loads and saves it then becomes the class's responsibility with no need for a GraphicHostState at all.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.