Here is a summary of the ** Memento pattern ** in the GoF design pattern.
--The English word Memento means ** souvenir **, ** keepsake **, ** seed of memory **. --In order to undo in an object-oriented program, you need to save the information that the instance has. --In order to restore an instance, you need to have free access to the information inside the instance. However, if you inadvertently allow access, the code will depend on the internal structure of the class. This is called ** encapsulation destruction **. --The Memento pattern is a method that introduces a role that represents the state of an instance and saves / restores it without breaking the encapsulation. ** ** --The GoF design patterns are classified as ** behavioral design patterns **.
This is a program that changes your money and belongings (fruits) according to the roll of the dice. Save or undo depending on the situation.
This is the class of the main character who plays the game. Create an instance of Memento.
Gamer.java
package game;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Random;
public class Gamer {
private int money;
private ArrayList<String> fruits = new ArrayList<String>();
private Random random = new Random();
private static String[] fruitsname = {
"Apple", "Grape", "banana", "Mandarin orange",
};
public Gamer(int money) {
this.money = money;
}
public int getMoney() {
return money;
}
//Bet ... Game progress
public void bet() {
//Roll the dice
int dice = random.nextInt(6) + 1;
if (dice == 1) {
//1st eye ... Increases your money
money += 100;
System.out.println("My money has increased.");
} else if (dice == 2) {
//2nd ... Half your money
money /= 2;
System.out.println("My money has been halved.");
} else if (dice == 6) {
//6 eyes ... get fruit
String f = getFruit();
System.out.println("fruits(" + f + ")I got");
fruits.add(f);
} else {
//Other than that ... nothing happens
System.out.println("Nothing happened.");
}
}
//Take a snapshot
public Memento createMemento() {
Memento m = new Memento(money);
Iterator it = fruits.iterator();
while (it.hasNext()) {
String f = (String) it.next();
if (f.startsWith("Delicious")) {
//Save only delicious fruits
m.addFruit(f);
}
}
return m;
}
//Do undo
public void restoreMemento(Memento memento) {
this.money = memento.money;
this.fruits = memento.getFruits();
}
public String toString() {
return "[money = " + money + ", fruits = " + fruits + "]";
}
private String getFruit() {
String prefix = "";
if (random.nextBoolean()) {
prefix = "Delicious";
}
return prefix + fruitsname[random.nextInt(fruitsname.length)];
}
}
A class that represents the state of Geme.
Memento.java
package game;
import java.util.ArrayList;
public class Memento {
int money;
ArrayList<String> fruits;
public int getMoney() {
return money;
}
Memento(int money) {
this.money = money;
this.fruits = new ArrayList<String>();
}
void addFruit(String fruit) {
fruits.add(fruit);
}
ArrayList<String> getFruits() {
return (ArrayList<String>) fruits.clone();
}
}
This class performs the main processing. Advance the game. It also saves an instance of Memento and restores Gamer's state if needed.
Main.java
import game.Gamer;
import game.Memento;
public class Main {
public static void main(String[] args) {
//The first money you have is 100
Gamer gamer = new Gamer(100);
//Save the initial state
Memento memento = gamer.createMemento();
for (int i = 0; i < 10; i++) {
System.out.println("==== " + i);
System.out.println("Current status:" + gamer);
//Advance the game
gamer.bet();
System.out.println("The money you have" + gamer.getMoney() + "It became a circle.");
if (gamer.getMoney() > memento.getMoney()) {
System.out.println("(Since it has increased a lot, let's save the current state)");
memento = gamer.createMemento();
} else if (gamer.getMoney() < memento.getMoney() / 2) {
System.out.println("(It has decreased a lot, so let's return to the previous state)");
gamer.restoreMemento(memento);
}
}
}
}
==== 0
Current status:[money = 100, fruits = []]
fruits(Delicious banana)I got
The money I have is now 100 yen.
==== 1
Current status:[money = 100, fruits = [Delicious banana]]
My money has increased.
The money I have is now 200 yen.
(Since it has increased a lot, let's save the current state)
==== 2
Current status:[money = 200, fruits = [Delicious banana]]
Nothing happened.
The money I have is now 200 yen.
==== 3
Current status:[money = 200, fruits = [Delicious banana]]
My money has increased.
The money I have is now 300 yen.
(Since it has increased a lot, let's save the current state)
==== 4
Current status:[money = 300, fruits = [Delicious banana]]
Nothing happened.
The money I have is now 300 yen.
==== 5
Current status:[money = 300, fruits = [Delicious banana]]
My money has been halved.
The money I have is now 150 yen.
==== 6
Current status:[money = 150, fruits = [Delicious banana]]
Nothing happened.
The money I have is now 150 yen.
==== 7
Current status:[money = 150, fruits = [Delicious banana]]
My money has increased.
The money I have is now 250 yen.
==== 8
Current status:[money = 250, fruits = [Delicious banana]]
My money has been halved.
The money I have is now 125 yen.
(It has decreased a lot, so let's return to the previous state)
==== 9
Current status:[money = 300, fruits = [Delicious banana]]
Nothing happened.
The money I have is now 300 yen.
The Memento pattern allows you to ** undo, redo, create work history, save current state **, and more. If you want to undo, you may be wondering if you should build that feature in the Gamer class. In the Main class, you decide "when to take a snapshot" and "when to undo" and hold the role of Memento. On the other hand, in the Gamer class, you will do the job of creating a Memento role and the task of returning your status using the given Memento role. You can see that the roles are divided in this way between the Main class and the Gamer class. If you divide the roles like this,
--I want to change to undo in multiple steps --I want to save the current state to a file as well as undo
Even if you want to make the correction, you don't need to change the Gamer role.
-** GoF design pattern summary **
This article and sample program were created based on the following books.
-** Introduction to design patterns learned in Java language **
It was very easy to understand and I learned a lot. Thank you. The detailed explanations of the design patterns and sample programs are written, so please take a look at the books as well.
Recommended Posts