Java设计模式-备忘录模式、备忘录模式应用场景是什么、又怎么使用

继续整理记录这段时间来的收获,详细代码可在我的Gitee仓库Java设计模式克隆下载学习使用!

6.11 备忘录模式

6.11.1 定义

又称快照模式,在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存此状态,以便后续需要时将该对象恢复到原先保存的状态

6.11.2 结构

  • 发起人角色(originator):记录当前时刻的内部状态信息,提供创备忘录和恢复备忘录数据的功能,实现其他业务功能,可以访问备忘录里的所有信息
  • 备忘录角色(memento):负责存储发起人的内部状态,在需要的时候提供这些内部状态给发起人
  • 管理者角色(Caretaker):对备忘录进行管理,提供保存与获取备忘录的功能,但其不能对备忘录内容进行访问与修改
  • 两个等效接口:
    • 窄接口:管理对象(和发起人对象之外的任何对象)看到的是备忘录的窄接口(narrow interface),此接口仅仅运行它把备忘录对象传给其他对象
    • 宽接口:发起人可以看到宽接口(wide interface),此接口运行它读取所有的数据,以便根据这些数据恢复这个发起人对象的内部状态

6.11.3 案例

6.11.3.1 白箱模式
  • 特点:对所有对象提供一个宽接口,违反了封闭原则
  • 游戏角色
public class GameRole {  
//    角色名称  
    private String name;  
//    生命力  
    private int vita;  
//    攻击力  
    private int attack;  
//    防御力  
    private int defender;  
    public int getVita() {  
        return vita;  
    }  
    public void setVita(int vita) {  
        this.vita = vita;  
    }  
    public int getAttack() {  
        return attack;  
    }  
    public void setAttack(int attack) {  
        this.attack = attack;  
    }  
    public int getDefender() {  
        return defender;  
    }  
    public void setDefender(int defender) {  
        this.defender = defender;  
    }  
    public String getName() {  
        return name;  
    }  
    public void setName(String name) {  
        this.name = name;  
    }  
    //    初始化状态  
    public void initState(){  
        this.attack = 100;  
        this.vita = 100;  
        this.defender = 100;  
    }  
//    战斗  
    public void fight(){  
        this.vita -= 50;  
        this.attack -= 50;  
        this.defender -= 50;  
    }  
//    保存状态  
    public RoleStateMemento saveState(){  
        return new RoleStateMemento(name,vita,attack,defender);  
    }  
//    恢复角色状态  
    public void recoverState(RoleStateMemento roleStateMemento){  
//        将备忘录对象中数据赋值给角色对象成员  
        this.vita = roleStateMemento.getVita();  
        this.attack = roleStateMemento.getAttack();  
        this.defender = roleStateMemento.getDefender();  
    }  
//    展示角色属性  
    public void display(){  
        System.out.println("角色" + name + "属性:");  
        System.out.println("角色生命力:" + this.vita);  
        System.out.println("角色攻击力:" + this.attack);  
        System.out.println("角色防御力:" + this.defender);  
    }  
}
  • 备忘录对象
public class RoleStateMemento {  
    //    角色名称  
    private String name;  
    //    生命力  
    private int vita;  
    //    攻击力  
    private int attack;  
    //    防御力  
    private int defender;  
    public int getVita() {  
        return vita;  
    }  
    public void setVita(int vita) {  
        this.vita = vita;  
    }  
    public int getAttack() {  
        return attack;  
    }  
    public void setAttack(int attack) {  
        this.attack = attack;  
    }  
    public int getDefender() {  
        return defender;  
    }  
    public void setDefender(int defender) {  
        this.defender = defender;  
    }  
    public String getName() {  
        return name;  
    }  
    public RoleStateMemento(String name, int vita, int attack, int defender) {  
        this.attack = attack;  
        this.vita = vita;  
        this.defender = defender;  
        this.name = name;  
    }  
    public RoleStateMemento() {  
    }  
}
  • 备忘录管理对象
public class RoleStateManage {  
//    用集合存储备忘录对象  
    private Map<String,RoleStateMemento> map = new HashMap<String,RoleStateMemento>();  
//    添加备忘录对象  
    public void addRoleStateMemento(RoleStateMemento roleStateMemento){  
        map.put(roleStateMemento.getName(),roleStateMemento);  
    }  
//    获取备忘录对象  
    public RoleStateMemento getRoleStateMemento(String name){  
        return map.get(name);  
    }  
}
  • 测试
    public static void main(String[] args) {  
        System.out.println("大战前-----------------------");  
//        创建角色  
        GameRole gameRole = new GameRole();  
        gameRole.setName("张三");  
//        初始化  
        gameRole.initState();  
//        展示  
        gameRole.display();  
//        保存状态  
        RoleStateMemento roleStateMemento = gameRole.saveState();  
        RoleStateManage roleStateManage = new RoleStateManage();  
        roleStateManage.addRoleStateMemento(roleStateMemento);  
        System.out.println("大战-----------------------");  
        gameRole.fight();  
//        展示  
        gameRole.display();  
        System.out.println("大战后-----------------------");  
//        恢复状态  
        roleStateMemento = roleStateManage.getRoleStateMemento("张三");  
        gameRole.recoverState(roleStateMemento);  
//        展示  
        gameRole.display();  
    }
  • 结果![[Pasted image 20230117212002.png]]

  • 类图![[Pasted image 20230117212119.png]]

6.11.4.1 黑箱模式
  • 改进:对发起任对象提供宽接口,为其它对象提供窄接口。具体是将备忘录对象设置为发起人的内部成员类
  • 抽象备忘录接口,供外部访问
public interface Memento {  
}
  • 游戏角色
public class GameRole {  
//    角色名称  
    private String name;  
//    生命力  
    private int vita;  
//    攻击力  
    private int attack;  
//    防御力  
    private int defender;  
    public int getVita() {  
        return vita;  
    }  
    public void setVita(int vita) {  
        this.vita = vita;  
    }  
    public int getAttack() {  
        return attack;  
    }  
    public void setAttack(int attack) {  
        this.attack = attack;  
    }  
    public int getDefender() {  
        return defender;  
    }  
    public void setDefender(int defender) {  
        this.defender = defender;  
    }  
    public String getName() {  
        return name;  
    }  
    public void setName(String name) {  
        this.name = name;  
    }  
    //    初始化状态  
    public void initState(){  
        this.attack = 100;  
        this.vita = 100;  
        this.defender = 100;  
    }  
//    战斗  
    public void fight(){  
        this.vita -= 50;  
        this.attack -= 50;  
        this.defender -= 50;  
    }  
//    保存状态  
    public RoleStateMemento saveState(){  
        return new RoleStateMemento(vita,attack,defender);  
    }  
//    恢复角色状态  
    public void recoverState(Memento memento){  
        RoleStateMemento roleStateMemento = (RoleStateMemento) memento;  
//        将备忘录对象中数据赋值给角色对象成员  
        this.vita = roleStateMemento.getVita();  
        this.attack = roleStateMemento.getAttack();  
        this.defender = roleStateMemento.getDefender();  
    }  
//    展示角色属性  
    public void display(){  
        System.out.println("角色" + name + "属性:");  
        System.out.println("角色生命力:" + this.vita);  
        System.out.println("角色攻击力:" + this.attack);  
        System.out.println("角色防御力:" + this.defender);  
    }  
    //备忘录对象
    private class RoleStateMemento implements Memento {  
        //    生命力  
        private int vita;  
        //    攻击力  
        private int attack;  
        //    防御力  
        private int defender;  
        public int getVita() {  
            return vita;  
        }  
        public void setVita(int vita) {  
            this.vita = vita;  
        }  
        public int getAttack() {  
            return attack;  
        }  
        public void setAttack(int attack) {  
            this.attack = attack;  
        }  
        public int getDefender() {  
            return defender;  
        }  
        public void setDefender(int defender) {  
            this.defender = defender;  
        }  
        public RoleStateMemento(int vita, int attack, int defender) {  
            this.attack = attack;  
            this.vita = vita;  
            this.defender = defender;  
        }  
    }  
}
  • 管理备忘录对象
public class RoleStateManage {  
//    用集合存储备忘录对象  
    private Map<String, Memento> map = new HashMap<String, Memento>();  
//    添加备忘录对象  
    public void addRoleStateMemento(String name,Memento memento){  
        map.put(name,memento);  
    }  
//    获取备忘录对象  
    public Memento getRoleStateMemento(String name){  
        return map.get(name);  
    }  
}
  • 测试
    public static void main(String[] args) {  
        System.out.println("大战前-----------------------");  
//        创建角色  
        GameRole gameRole = new GameRole();  
        gameRole.setName("张三");  
//        初始化  
        gameRole.initState();  
//        展示  
        gameRole.display();  
//        保存状态  
        Memento roleStateMemento = gameRole.saveState();  
        RoleStateManage roleStateManage = new RoleStateManage();  
        roleStateManage.addRoleStateMemento("张三",roleStateMemento);  
        System.out.println("大战-----------------------");  
        gameRole.fight();  
//        展示  
        gameRole.display();  
        System.out.println("大战后-----------------------");  
//        恢复状态  
        Memento memento= roleStateManage.getRoleStateMemento("张三");  
        gameRole.recoverState(memento);  
//        展示  
        gameRole.display();  
    }
  • 结果不变,同上
  • 类图![[Pasted image 20230117214818.png]]

6.11.4 优缺点

6.11.4.1 优点
  • 提供了一种可以恢复状态的机制,当用户需要时能方便的将数据恢复到某个历史的状态
  • 实现了内部状态的封装,除了创建它的发起人外,其它对象都不能访问这些状态信息
  • 简化了发起人类,发起人不需要管理和保存其内部状态的备份,所有状态信息保存在备忘录,并有管理者进行管理,复合单一职责原则
6.11.4.2 缺点
  • 资源消耗大,若保存频繁或内部状态信息过多,会消耗内存

6.11.5 使用场景

  • 需要保存和恢复数据的场景,如游戏存档
  • 需要提供一个可回滚操作,如记事本,Word等
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值