0

I've question about the philosophy of createMemento() in Originator class in Memento Pattern.

My teacher said:

now that Originator class no longer stores Memento objects internally, we should give it two new methods; createMemento() and setMemento().

The createMemento() method stores the current state of the Originator inside a Memento object and returns it. So we call this method and say, "Hey, save your current state and give it to me", we'll get an Memento object.

I'm confused. Because when I was trying to implement the Originator class that stores a list of Memento internally ,I still needed to have this createMemento() method.

my class:

public class MyOriginator {

    private String content;
    
    //stores a list of Momento internally
    private List<Momento> previousStates;

    public MyOriginator() {

        previousStates = new ArrayList<>();
    }

    public void push() {
        previousStates.add(createMomento());
    }

    // need to have it.
    private Momento createMomento() {
        return new Momento(content);
    }

    public void pop() {

        int lastIndex = previousStates.size() - 1;

        this.content = previousStates.get(lastIndex).getContent();

        previousStates.remove(lastIndex);
    }
}

So createMemento() seems to have nothing to do with storing or not storing Memento objects internally and storing or not storing Memento objects internally is not the reason of making and using of createMemento().

What is the reason for using and creating this method? in both case ( stores Memento objects internally and not storing Memento objects internally), I had to implement that method.

3
  • please don't cross-post: stackoverflow.com/questions/66824824/… "Cross-posting is frowned upon as it leads to fragmented answers splattered all over the network..."
    – gnat
    Mar 27 '21 at 7:15
  • This push/pop thing you made is not the Memento pattern. You need to give the memento instance to some other class/object to hold on to (so that the originator doesn't have to keep track of who the memento is for, when to reset the memento and why, etc. - the external object is responsible for that). But the memento instance needs to somehow store or encode the private state of the originator at the time of the request, so you need a public method createMemento() that can access that private state to create the memento object and return it to this other object (the caretaker). Mar 27 '21 at 8:03
2

The intent of the memento pattern is according to GoF:

Without violating encapsulation, capture and externalize an object internal state so that this object can be restored to this state later.

Your implementation is different: by keeping the mementos internally in a stack, you make it part of the object state. You therefore have an object aware of its own history. It’s a very different design. And you force the behavior of a step by step restore to each successive previous state for all possible use of the object. Some would worry about the respect of the single responsibility principle in such a design.

The GoF memento gives the responsibility of keeping the memento to a caretaker. This has the advantage of separation of concerns and greater reusability. If you want to manage mementos in a LIFO way, you can use a stack. But maybe you’ll have several snapshots and want to go back directly to any of those snapshot. With the memento pattern, the memento and the originator would stay unchanged. Only the caretaker and the surrounding classes would change to meet different needs.

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.