lundi 11 janvier 2016

class template for command pattern that supports undo

For simple commands that aren’t undoable and don’t require arguments, we can use a class template to parameterize the command’s receiver. We’ll define a template subclass SimpleCommand for such commands. SimpleCommand is parameterized by the Receiver type and maintains a binding between a receiver object and an action stored as a pointer to a member function. enter image description here

enter image description here Keep in mind that this solution only works for simple commands. More complex commands that keep track of not only their receivers but also arguments and/or undo state require a Command subclass.

From : GoF

Why commands that require to save undo state need command subclass?

Why cannot we do something like this?

class Memento
{


};


class myMemento : public Memento
{

friend myclass;

};

class yourMemento : public Memento
{

friend yourclass;
};

class SupportsMemento
{
public:
    Memento * getMemento();
    reinstateMemento(Memento *);

};

class myclass
{
    myMemento * getMemento();
    reinstateMemento(myMemento *); // breaks LSP
}

template<class Receiver>
class StandardCommand : public Command
{
public:
    typedef void (Command::*Action)();

    StandardCommand(Reciever * r, Action a):
        _receiver(r), _action(a){}
    virtual void execute();
    virtual void unexecute();
private:
    Receiver * _receiver;
    Action _action;
    Memento * m;
};

template<class Receiver>
void StandardCommand<Receiver>::execute()
{
    m=_reciever->getMemento();
    (_reciever->*Action)();
};

template<class Receiver>
void StandardCommand<Receiver>::unexecute()
{
    _receiver->reinstante_Memento(m);
};

Is it because it breaks LSP, or is there any other reason behind this?

Aucun commentaire:

Enregistrer un commentaire