Today i'm gonna show the Memento design pattern in action. The Memento design pattern is a very useful programming design pattern whenever you need to perform save, undo and restore functions.
I'm assuming here you already know the concepts and i'll be focusing on practise. The example i will provide is a nice way to show it how it could looks like. You can always come back here, take it, adapt it and use it in your applictions as you may need. So be sure you bookmark it or join the group here on the right side of this post subscribing it.
First of all, let's take a look at the UML diagram of it. After that we will take the analogy for our example.
The UML Diagram of the Memento Pattern
Pay close attention, because once you understand that, everything will become clear and simple to understand. That's the reason I'm putting always the UML first. That way you'll get an eye for it with the time.
The example
In our example we will see, how we could perform save and undo actions restoring objects from a text file.The Memento
That's the generic interface you could use while dealing with memento's capabilities. We will implement the memento on the fly in the Originator bellow. In other words, as soon as we need it in line.// 1 STEP: DEFINE THE MEMENTO public interface Memento < T > { T getMemento(); void setMemento(T state); }
The Originator
That's the generic interface we will use to implement the Originator. I will create it also on the fly in the client. In a few seconds bellow. :)//2 STEP: DEFINE THE ORIGINATOR public interface Save < T > extends Memento < T > { Memento < T > save(); void restore(Memento < T > memento); }
The Interface Undo
That's the generic interface we will use to create the care taker. I will create it also on the fly in the client. Be patient. :)//3 STEP: DEFINE THE CARETAKER public interface Undo < T > { public void addMemento(Memento < T > state) ; public Memento < T > getMemento(int index); }
The concrete CareTaker
That's the abstract implementation of the generic interface. I will create it also on the fly in the client. Stay tuned. :)//4 STEP: IMPLEMENT A ABSTRACTCARATAKER public abstract class UndoCareTaker < T > implements Undo < T > { private List < Memento < T > > mementoList = new ArrayList < Memento < T > > (); public void addMemento(Memento < T > state) { if (state != null) { mementoList.add(state); } } public Memento < T > getMemento(int index) { int min = 0; int max = mementoList.size()-1; if(mementoList.isEmpty()){ String msg = "CareTaker has no entry! Passed index:"; throw new IndexOutOfBoundsException(msg + index); } if(!(index > = min && index < = max)){ String msg = "Passed index:"+index+" > Allowed index range: "; throw new IndexOutOfBoundsException(msg + min + " - " + max); } return mementoList.get(index); } }
The Originator Ifself
That's the abstract implementation of the interface generic interface Save.//5 STEP: IMPLEMENT A ABSTRACTORIGINATOR public abstract class SaveOriginator < T > implements Save < T >{ private T state; public void setMemento(T state) {this.state = state;} public T getMemento() {return state;} public void restore(Memento < T > memento) {setMemento(memento.getMemento());} public Memento < T > save() { Memento < T > memento = new Memento < T > () { // created on the fly as i promissed! :) private T state; @Override public void setMemento(T state) {this.state = state;} @Override public T getMemento() {return state;} }; memento.setMemento(state); return memento; } }
The Test
Finally, let's see how it works in practise.public class Client { public static void main(String[] args) { Save < String > originator = new SaveOriginator < String > (){};//created on the fly Undo < String > careTaker = new UndoCareTaker < String > (){};//created on the fly originator.setMemento("State #1"); originator.setMemento("State #2"); careTaker.addMemento(originator.save()); originator.setMemento("State #3"); careTaker.addMemento(originator.save()); originator.setMemento("State #4"); System.out.println("Current State: " + originator.getMemento()); originator.restore(careTaker.getMemento(0)); System.out.println("First saved State: " + originator.getMemento()); originator.restore(careTaker.getMemento(1)); System.out.println("Second saved State: " + originator.getMemento()); } }
That's all! Hope you like it!
😱👇 PROMOTIONAL DISCOUNT: BOOKS AND IPODS PRO 😱👇
Be sure to read, it will change your life!
Show your work by Austin Kleon: https://amzn.to/34NVmwx
This book is a must read - it will put you in another level! (Expert)
Agile Software Development, Principles, Patterns, and Practices: https://amzn.to/30WQSm2
Write cleaner code and stand out!
Clean Code - A Handbook of Agile Software Craftsmanship: https://amzn.to/33RvaSv
This book is very practical, straightforward and to the point! Worth every penny!
Kotlin for Android App Development (Developer's Library): https://amzn.to/33VZ6gp
Needless to say, these are top right?
Apple AirPods Pro: https://amzn.to/2GOICxy
😱👆 PROMOTIONAL DISCOUNT: BOOKS AND IPODS PRO 😱👆