备忘录模式,在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样以后就可将该对象恢复到原先保存的状态。
这个模式也很简单,最主要是一种思想。逻辑缜密的人在设计框架时必然走到这里。我们看看UML类图。
基本逻辑代码:
class Originator{
private String state;
public Memento createMemento(){
return (new Memento(state));
}
public void setMemento(Memento m{
state = m.state;
}
public void show(){
//输出state
}
}
class Memento{
private String state;
public Memento(String state){
this.state = state;
}
poublic String getState(){
return state;
}
}
class Caretaker{
private Memento m;
public void saveMemento(Memento m){
this.m = m;
}
public Memento getMemento(){
return m;
}
}
客户端调用
static void mian(String[] args){
Originator o = new Originator();
o.state = "on";
Caretaker c = new Caretaker();
c.setMemento(o.createMemento());
o.state = "off";
o.setMemento(c.getMemento()):
}
代码一看都能明白,很简单。相信大家很多人小时候都玩过卡带游戏,带保存进度的那种游戏。每次在一个节点保存进度,在进入下一个节点,一旦失败了。可以恢复节点处的状态,这个就是典型的备忘录模式。这里就以游戏有例子。
备忘录类
package com.abings.mementomodel.MementoModel;
/**
* Created by HaomingXu on 2016/9/13.
*/
public class Memento {
public String name;//姓名
public String sex;//性别
public String style;//职业
public String attckZB;//攻击装备
public String defineZB;//防御装备
public String lifeZB;//指环装备
public int attack;//攻击力
public int define;//防御值
public int life;//生命值
public int lan;//法力值
public Memento(String name, String sex, String style, String attckZB, String defineZB, String lifeZB, int attack, int define, int life, int lan) {
this.name = name;
this.sex = sex;
this.style = style;
this.attckZB = attckZB;
this.defineZB = defineZB;
this.lifeZB = lifeZB;
this.attack = attack;
this.define = define;
this.life = life;
this.lan = lan;
}
public Memento(){
}
public int getLan() {
return lan;
}
public void setLan(int lan) {
this.lan = lan;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public String getStyle() {
return style;
}
public void setStyle(String style) {
this.style = style;
}
public String getAttckZB() {
return attckZB;
}
public void setAttckZB(String attckZB) {
this.attckZB = attckZB;
}
public String getDefineZB() {
return defineZB;
}
public void setDefineZB(String defineZB) {
this.defineZB = defineZB;
}
public String getLifeZB() {
return lifeZB;
}
public void setLifeZB(String lifeZB) {
this.lifeZB = lifeZB;
}
public int getAttack() {
return attack;
}
public void setAttack(int attack) {
this.attack = attack;
}
public int getDefine() {
return define;
}
public void setDefine(int define) {
this.define = define;
}
public int getLife() {
return life;
}
public void setLife(int life) {
this.life = life;
}
@Override
public String toString() {
return "玩家{" +
"姓名:'" + name + '\'' +
"\n 性别:'" + sex + '\'' +
"\n 职业:'" + style + '\'' +
"\n 攻击装备:'" + attckZB + '\'' +
"\n 防御装备:'" + defineZB + '\'' +
"\n 指环:'" + lifeZB + '\'' +
"\n 攻击力:" + attack +
"\n 防御力:" + define +
"\n 生命值:" + life +
"\n 魔法值:" + lan +
'}';
}
}
玩家类
package com.abings.mementomodel.Builder;
import com.abings.mementomodel.MementoModel.Memento;
/**
* Created by HaomingXu on 2016/9/13.
*/
public class Player extends Memento {
public Player(String name, String sex, String style, String attckZB, String defineZB, String lifeZB, int attack, int define, int life, int lan) {
super(name, sex, style, attckZB, defineZB, lifeZB, attack, define, life, lan);
}
public Player(){
}
//创建备忘录
public Memento createMemento(){
return (new Memento(name,sex,style,attckZB,defineZB,lifeZB,attack,define,life,lan));
}
//恢复状态
public void setMemento(Memento memento){
this.name = memento.getName();
this.sex = memento.getSex();
this.style = memento.getStyle();
this.attckZB = memento.getAttckZB();
this.defineZB = memento.getDefineZB();
this.lifeZB = memento.getLifeZB();
this.attack = memento.getAttack();
this.define = memento.getDefine();
this.life = memento.getLife();
this.lan = memento.getLan();
}
public void fightWithBoss(){
this.life = 0;
this.lan = 0;
}
@Override
public String toString() {
return super.toString();
}
}
package com.abings.mementomodel.Builder;
/**
* Created by HaomingXu on 2016/9/13.
*/
public abstract class Builder {
public abstract void setLan() ;
public abstract void setName() ;
public abstract void setSex() ;
public abstract void setStyle() ;
public abstract void setAttckZB() ;
public abstract void setDefineZB() ;
public abstract void setLifeZB() ;
public abstract void setAttack() ;
public abstract void setDefine() ;
public abstract void setLife() ;
public abstract Player getPlayer();
}
建造者中指挥者
package com.abings.mementomodel.Builder;
/**
* Created by HaomingXu on 2016/9/13.
*/
public class Director {
public static Player cratePlayer(Builder builder){
builder.setName();
builder.setSex();
builder.setAttack();
builder.setAttckZB();
builder.setDefine();
builder.setDefineZB();
builder.setLan();
builder.setLifeZB();
builder.setLife();
builder.setStyle();
return builder.getPlayer();
}
}
package com.abings.mementomodel.MementoModel;
/**
* Created by HaomingXu on 2016/9/13.
*/
public class Caretaker {
private Memento memento;
public Memento getMemento() {
return memento;
}
public void setMemento(Memento memento) {
this.memento = memento;
}
}
客户端
package com.abings.mementomodel;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import com.abings.mementomodel.Builder.Director;
import com.abings.mementomodel.Builder.Player;
import com.abings.mementomodel.Builder.ZhanShiPlayer;
import com.abings.mementomodel.MementoModel.Caretaker;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//创建角色,魔族战士
Player player = Director.cratePlayer(new ZhanShiPlayer());
//到了保存记录节点
Caretaker caretaker = new Caretaker();
//打boss之前保存状态
caretaker.setMemento(player.createMemento());
//打Boss之前的状态
Log.i("Tag", player.toString());
//单挑BOSS失败了
player.fightWithBoss();
//单挑之后的状态
Log.i("Tag", player.toString());
//读取记录,满血复活
player.setMemento(caretaker.getMemento());
//读取记录之后的状态
Log.i("Tag", player.toString());
}
}
运行结果:
09-13 12:58:13.615 27181-27181/com.abings.mementomodel I/Tag: 玩家{姓名:'魔尊重楼'
性别:'男'
职业:'魔族战士'
攻击装备:'魔族至尊饮血剑'
防御装备:'魔族至尊反甲'
指环:'魔族至尊狂澜铠甲'
攻击力:3500
防御力:3000
生命值:6000
魔法值:1500}
09-13 12:58:13.615 27181-27181/com.abings.mementomodel I/Tag: 玩家{姓名:'魔尊重楼'
性别:'男'
职业:'魔族战士'
攻击装备:'魔族至尊饮血剑'
防御装备:'魔族至尊反甲'
指环:'魔族至尊狂澜铠甲'
攻击力:3500
防御力:3000
生命值:0
魔法值:0}
09-13 12:58:13.615 27181-27181/com.abings.mementomodel I/Tag: 玩家{姓名:'魔尊重楼'
性别:'男'
职业:'魔族战士'
攻击装备:'魔族至尊饮血剑'
防御装备:'魔族至尊反甲'
指环:'魔族至尊狂澜铠甲'
攻击力:3500
防御力:3000
生命值:6000
魔法值:1500}
运用起来也很简单,客户端代码相当简洁。代码的扩展性,灵活性,维护性,可复用性都得到了一定的提升。只是这里面的逻辑有点绕。多学多用才是真理、git: