大话设计模式读书笔记——备忘录模式


1. 需求

请用代码实现以下场景:=一个游戏里面的角色有生命力、攻击力、防御力等数据,在打Boss前和后一定会不一样的,我们允许玩家如果感觉与Boss决斗的效果不理想可以让游戏恢复到决斗前。

2. 代码版本1.0

2.1 游戏角色类

public class GameRole {
    //生命值
    private int vitality;
    //攻击力
    private int attack;
    //防御力
    private int defense;
    public int getVitality() {
        return vitality;
    }

    public void setVitality(int vitality) {
        this.vitality = vitality;
    }

    public int getAttack() {
        return attack;
    }

    public void setAttack(int attack) {
        this.attack = attack;
    }

    public int getDefense() {
        return defense;
    }

    public void setDefense(int defense) {
        this.defense = defense;
    }

    //状态显示
    public void displayState(){
        System.out.println("角色当前状态:");
        System.out.println("体力:"+this.vitality);
        System.out.println("攻击力:"+this.attack);
        System.out.println("防御力:"+this.defense);
    }
    //获取初始状态(数据通常来自本机磁盘或者远程数据接口)
    public void getInitState(){
        this.vitality=100;
        this.attack=100;
        this.defense=100;
    }
    //战斗(跟BOSS战斗后数据损耗成0)
    public void fight(){
        this.vitality=0;
        this.attack=0;
        this.defense=0;
    }
}

2.2 客户端代码

     //大战Boss前
     GameRole role = new GameRole();
     role.getInitState();
     role.displayState();

     //保存进度
     GameRole backup = new GameRole();
     backup.setVitality(role.getVitality());
     backup.setAttack(role.getAttack());
     backup.setDefense(role.getDefense());

     //大战Boss,损耗严重
     role.fight();
     //显示状态
     role.displayState();

     //游戏进度回复
     role.setVitality(backup.getVitality());
     role.setAttack(backup.getAttack());
     role.setDefense(backup.getDefense());

     //显示状态
     role.displayState();

2.3 弊端

游戏角色的细节暴露给客户端,客户端的责任过大。为了解决这个弊端,下面介绍一个模式—备忘录模式

3. 备忘录模式

3.1 概念

备忘录(Memento):在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样以后就可将该对象恢复到原先保存的状态。

3.2 缺点

角色状态需要完整存储到备忘录对象中,如果状态数据很大很多,那么在资源消耗上,备忘录对象会非常耗内存。

3.3 案例代码

3.3.1 UML类图

在这里插入图片描述

3.3.2 发起人(Originator)类

负责创建一个备忘录Memento,用以记录当前时刻它的内部状态,并可使用备忘录恢复内部状态。Originator
可根据需要决定Memento存储Originator的哪些内部状态。

public class Originator {
    //状态
    private String state;
    public String getState() {
        return state;
    }

    public void setState(String state) {
        this.state = state;
    }

    //显示数据
    public void show(){
        System.out.println("State:"+this.state);
    }

    //创建备忘录
    public Memento createMemento(){
        return new Memento(this.state);
    }
    //恢复备忘录
    public void recoveryMemento(Memento memento){
        this.setState(memento.getState());
    }
}

3.3.3 备忘录(Memento)类

负责存储Originator对象的内部状态,并可防止Originator以外的其他对象访问备忘录Memento。备忘录有两个接口,Caretaker只能看到备忘录的窄接口,它只能将备忘录传递给其他对象。Originator能够看到一个宽接口,允许它访问返回到先前状态所需的所有数据。

public class Memento {
    private String state;

    public Memento(String state){
        this.state = state;
    }
    public String getState() {
        return state;
    }

    public void setState(String state) {
        this.state = state;
    }
}

3.3.4 管理者(Caretaker)类

负责保存好备忘录Memento,不能对备忘录的内容进行操作或检查。

public class Caretaker {
    public Memento memento;
    public Memento getMemento() {
        return memento;
    }

    public void setMemento(Memento memento) {
        this.memento = memento;
    }
}

3.3.5 客户端代码

     //Originator初始状态,属性状态为”On“
     Originator o = new Originator();
     o.setState("On");
     o.show();

     Caretaker c = new Caretaker();
     //保存状态,由于有了很好的封装,可以隐藏Originator的实现细节
     c.setMemento(o.createMemento());

     //Originator改变了状态属性为”Off“
     o.setState("Off");
     o.show();

     //恢复原初始状态
     o.recoveryMemento(c.getMemento());
     o.show();

4. 代码版本2.0(备忘录模式实现)

4.1 UML类图

在这里插入图片描述

4.2 游戏角色类

public class GameRole {
    //生命值
    private int vitality;
    //攻击力
    private int attack;
    //防御力
    private int defense;
    public int getVitality() {
        return vitality;
    }

    public void setVitality(int vitality) {
        this.vitality = vitality;
    }

    public int getAttack() {
        return attack;
    }

    public void setAttack(int attack) {
        this.attack = attack;
    }

    public int getDefense() {
        return defense;
    }

    public void setDefense(int defense) {
        this.defense = defense;
    }

    //状态显示
    public void displayState(){
        System.out.println("角色当前状态:");
        System.out.println("体力:"+this.vitality);
        System.out.println("攻击力:"+this.attack);
        System.out.println("防御力:"+this.defense);
    }
    //获取初始状态(数据通常来自本机磁盘或者远程数据接口)
    public void getInitState(){
        this.vitality=100;
        this.attack=100;
        this.defense=100;
    }
    //战斗(跟BOSS战斗后数据损耗成0)
    public void fight(){
        this.vitality=0;
        this.attack=0;
        this.defense=0;
    }

    //保存角色状态
    public RoleStateMemento saveState(){
        return new RoleStateMemento(this.vitality,this.attack,this.defense);
    }

    //回复角色状态
    public void recoveryState(RoleStateMemento memento){
        this.setVitality(memento.getVitality());
        this.setAttack(memento.getAttack());
        this.setDefense(memento.getDefense());
    }
}

4.3 角色状态存储箱类

public class RoleStateMemento {
    private int vitality;
    private int attack;
    private int defense;

    //将生命力、攻击力、防御力存入状态存储对象中
    public RoleStateMemento(int vitality,int attack,int defense){
        this.vitality = vitality;
        this.attack = attack;
        this.defense = defense;
    }

    public int getVitality() {
        return vitality;
    }

    public void setVitality(int vitality) {
        this.vitality = vitality;
    }

    public int getAttack() {
        return attack;
    }

    public void setAttack(int attack) {
        this.attack = attack;
    }

    public int getDefense() {
        return defense;
    }

    public void setDefense(int defense) {
        this.defense = defense;
    }
}

4.4 角色状态管理者类

public class RoleStateCaretaker {
    private RoleStateMemento memento;
    public RoleStateMemento getMemento() {
        return memento;
    }

    public void setMemento(RoleStateMemento memento) {
        this.memento = memento;
    }
}

4.5 客户端代码

     //大战Boss前
     GameRole role = new GameRole();
     role.getInitState();
     role.displayState();

     //保存进度
     RoleStateCaretaker stateAdmin = new RoleStateCaretaker();
     stateAdmin.setMemento(role.saveState());

     //大战BOSS,损耗严重
     role.fight();
     //显示状态
     role.displayState();

     //游戏进度恢复
     role.recoveryState(stateAdmin.getMemento());

     //显示状态
     role.displayState();

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

头盔程序员

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值