samedi 27 février 2016

Protect a set_state() function in State Pattern

I want to create a Switch, which can take on two states: TurnedOn and TurnedOff.

Let's say I have this basic setup:

class SwitchState  // Abstract Class for the State Interface
{
public:
    virtual ~SwitchState(void) { /* */ }
    virtual void flip(Switch* swtch) = 0;
};

class TurnedOn: public SwitchState  // First State class
{
public:
    ~TurnedOn(void) { /* */ }
    void flip(Switch* swtch);
};

class TurnedOff: public SwitchState  // Second State class
{
public:
    ~TurnedOff(void) { /* */ }
    void flip(Switch* swtch);
};

class Switch  // This will be the State Context
{
public:
    Switch(Light* light): _state(new FlippedDown{light}) { /* */ }
    void flip(void);  // This will change the _state data member

protected:
    SwitchState* _state{};
};

So I can make a Switch object, call switch.flip(). This member function will look like this:

void Switch::flip(void)
{
    this->_state->flip(this);
}

Which will then in turn call:

void TurnedOff::flip(Switch* swtch)
{
    swtch->_state = new TurnedOn{};  // ERROR: _state is protected!
}

I see no way to set the _state of the Switch class without either exposing _state or creating a setter.

But if I'd do this, I could just set the state of the Switch without calling flip().

Is there some clever and/or established way to circumvent this?

Aucun commentaire:

Enregistrer un commentaire