今回は Memento パターン(一覧)。
Memento ・・・記念の品,形見; 思い出の種
Memento パターンの登場人物
- @Caretaker → 型
- mementoType : Class<?>
- @Originator → 型
- mementoType : Class<?>
- @CreateMemento → メソッド
- @RestoreMemento → メソッド
- @Memento → 型
- @GetProtectedInfo → メソッド
- @GetPublicInfo → メソッド
アノテーション定義
上記の定義の具体的な Java コード。
package org.waman.tools.design.gof.behavioral; import java.lang.annotation.*; public final class MementoPattern { private MementoPattern(){} @Target(ElementType.TYPE) public static @interface Memento{ @Inherited @Target(ElementType.METHOD) public static @interface GetProtectedInfo{} @Inherited @Target(ElementType.METHOD) public static @interface GetPublicInfo{} } @Target(ElementType.TYPE) public static @interface Originator{ Class<?> mementoType() default Void.class; @Inherited @Target(ElementType.METHOD) public static @interface CreateMemento{} @Inherited @Target(ElementType.METHOD) public static @interface RestoreMemento{} } @Target(ElementType.TYPE) public static @interface Caretaker{ Class<?> mementoType() default Void.class; } }
サンプルコード in 『Java 言語で学ぶデザインパターン入門』
Memento.java
@Memento 役のクラス。
import java.util.*; import org.waman.tools.design.gof.behavioral.MementoPattern; import org.waman.tools.design.gof.behavioral.MementoPattern.Memento.GetProtectedInfo; import org.waman.tools.design.gof.behavioral.MementoPattern.Memento.GetPublicInfo; @MementoPattern.Memento public class Memento { int money; final List<String> fruits = new ArrayList<String>(); Memento(int money) { this.money = money; } @GetPublicInfo public int getMoney() { return money; } @GetProtectedInfo void addFruit(String fruit) { fruits.add(fruit); } @GetProtectedInfo List<String> getFruits() { return new ArrayList<String>(fruits); } }
Gamer.java
@Originator 役のクラス。
import java.util.*; import org.waman.tools.design.gof.behavioral.MementoPattern; import org.waman.tools.design.gof.behavioral.MementoPattern.Originator.CreateMemento; import org.waman.tools.design.gof.behavioral.MementoPattern.Originator.RestoreMemento; @MementoPattern.Originator(mementoType = Memento.class) public class Gamer { private int money; private List<String> fruits = new ArrayList<String>(); ... @CreateMemento public Memento createMemento() { Memento m = new Memento(money); for(String fruit: fruits) { if (fruit.toString().startsWith("おいしい")) m.addFruit(fruit); } return m; } @RestoreMemento public void restoreMemento(Memento memento) { this.money = memento.money; this.fruits = memento.getFruits(); } ... }
Main.java
@Caretaker 役のクラス。
import org.waman.tools.design.gof.behavioral.MementoPattern; import sample.gof.behavioral.memento.game.Gamer; import sample.gof.behavioral.memento.game.Memento; @MementoPattern.Caretaker(mementoType = Memento.class) public class Main { public static void main(String[] args) { Gamer gamer = new Gamer(100); Memento memento = gamer.createMemento(); for (int i = 0; i < 100; i++) { ... if (gamer.getMoney() > memento.getMoney()) { System.out.println(" (だいぶ増えたので、現状の状態を保存しておこう)"); memento = gamer.createMemento(); } else if (gamer.getMoney() < memento.getMoney() / 2) { System.out.println(" (だいぶ減ったので、以前の状態に復帰しよう)"); gamer.restoreMemento(memento); } ... } } }