jeudi 24 novembre 2016

How to use the memento design pattern?

I'm very confused about how the memento is supposed to be implemented.

I understand the Memento has a State. And the Memento Pattern is used to store different (previous) states so that one can restore an object to previous states,

Well lets say I have multiple objects, each of this comes with 10 attributes, 5 of which stay the same throughout the life of each individual object, but 5 of which change. So i need, for each object to save it's previous states and go back to them.

The question:

How do I apply the Memento Pattern with these objects?

My idea so far:

So Memento Pattern has 3 classes, Memento of which you create many, one for each state. Caretaker which stores all the previous states of an object AKA Mementos. And then the Originator that creates Mementos and also gets the states from a Memento.

This would mean that each object instance would require it's own Caretaker instance (a list of it's previous states), and this Caretaker would have Mementos with the previous states of this object's 5 attributes (and also the current state or only previous ones?), but all objects with a caretaker can use the same Originator instance because the Originator can be used to create new mementos into any Caretaker.

Is this how it would be implemented or am I misunderstanding it?

It would look something like this:

Originator and Memento class

public class Memento {
   private Object1Attributes state;

   public Memento(Object1Attributes state){
      this.state = state;
   }

   public Object1Attributes getState(){
      return state;
   }    
}


static class Originator {
   private Object1Attributes state;

   public Memento saveStateToMemento(){
      return new Memento(state);
   }

   public void getStateFromMemento(Memento Memento){
      state = Memento.getState();
   }

   public void setState(Object1Attributes state){
      this.state = state;
   }

   public Object1Attributes getState(){
      return state;
   }

}

Other object

public class Object1Attributes{
    string attribute1;
    int attribute2;
    someObject attribute3;
    someObject attribute4;
    someObject attribute5;
}

public class Object1 {

    CareTaker careTaker = new CareTaker();

    Object1Attributes;

    string attribute6;
    int attribute7;
    someObject attribute8;
    someObject attribute9;
    someObject attribute10;


    public void returnToPreviousState(){
        if(caretaker.Length()>0){
            Object1Attributes = originator.getStateFromMemento(careTaker.get(caretaker.Length()-1));
            caretaker.remove(caretaker.Length()-1);
        }
   }

    public void newState(ObjectAttributes OA){
        originator.setState(OA);
        this.ObjectAttributes = OA;
        this.caretaker.add(originator.saveStateToMemento());

    }

}

Another option

would be making the Memento class and the Originator class hold the 5 attributes, instead of encapsulating the 5 attributes inside another class. Like so:

public class Originator {
    string attribute1;
    int attribute2;
    someObject attribute3;
    someObject attribute4;
    someObject attribute5;

   public Memento saveStateToMemento(){
      return new Memento(attribute1, attribute2, attribute3, attribute4, attribute5);
   }

   public void setAttribute1(string state){
      this.attribute1 = state;
   }

   public void setAttribute2(int state){
      this.attribute2 = state;
   }

}

This way each Object1 instance would hold its own instance of Originator instead of Object1Attributes though, and this Originator would contain the current state of the attributes in the object1 instance; I don't know which way is the correct way of implementing the pattern.

All examples online use mementos to store a "state" which is just a string, none of them involve the creation of multiple objects that can have multiple states, so that's why I'm so unsure.

Aucun commentaire:

Enregistrer un commentaire