设计模式——备忘录模式

Posted 沙中世界

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了设计模式——备忘录模式相关的知识,希望对你有一定的参考价值。

备忘录模式又称快照模式,是行为模式之一;

备忘录模式的应用场景是对某些对象做出了改变之后,又需要恢复到改变之前的状态!常常和命令模式结合使用...

备忘录中的三张角色;

1、原始角色,需要具有创建备忘录和根据备忘录恢复状态的方法

/*
 * Copyright (c) 2017. Xiaomi.Co.Ltd All rights reserved
 */

package com.pt.memo;

/**
 * @description 游戏角色
 * @author panteng
 * @date 17-2-24.
 */
public class Player {
    String name;    //角色名称
    Integer HP;     //血量
    Weapon weapon;  //武器

    public Player(){
    }

    public Player(String name, Integer HP, Weapon weapon){
        this.name = name;
        this.HP = HP;
        this.weapon = weapon;
    }
    public Memotor createMemotor(){
        //此处也并不是必须定义成final,定义成final这样可能会导致无法回收,但可以更有效的防止备忘录被修改
        final Memotor memotor = new Memotor(this.HP, this.weapon);
        return memotor;
    }

    /**
     * 深复制与浅复制的使用因场景而定
     * @return
     * @throws Exception
     */
    public Memotor createMemotorByDeepCopy() throws Exception{
        //采用深复制
        final Memotor memotor = new Memotor(new Integer(this.HP), (Weapon) this.weapon.deepClone());
        return memotor;
    }

    public void recover(Memotor memotor){
        this.HP = memotor.getHP();
        this.weapon = memotor.getWeapon();
    }

    public String getName(){
        return name;
    }
    public void setName(String name){
        this.name = name;
    }
    public Integer getHP(){
        return HP;
    }
    public void setHP(Integer HP){
        this.HP = HP;
    }
    public Weapon getWeapon(){
        return weapon;
    }
    public void setWeapon(Weapon weapon){
        this.weapon = weapon;
    }

    public void showState(){
        System.out.println(this.name + " HP:" + this.HP + " weapon:" + weapon);
    }
}
Player

武器类

/*
 * Copyright (c) 2017. Xiaomi.Co.Ltd All rights reserved
 */

package com.pt.memo;

import com.pt.prototype.PrototypeModle;

/**
 * @description 武器类
 * @author panteng
 * @date 17-2-24.
 */
public class Weapon extends PrototypeModle {
    String name;            //武器名称
    Float attackDistance;   //攻击距离
    Float ATK;              //攻击力
    public Weapon(){
    }
    public Weapon(String name, Float attackDistance, Float ATK){
        this.name = name;
        this.attackDistance = attackDistance;
        this.ATK = ATK;
    }

    public String getName(){
        return name;
    }
    public void setName(String name){
        this.name = name;
    }
    public Float getAttackDistance(){
        return attackDistance;
    }
    public void setAttackDistance(Float attackDistance){
        this.attackDistance = attackDistance;
    }
    public Float getATK(){
        return ATK;
    }
    public void setATK(Float ATK){
        this.ATK = ATK;
    }

    /**
     * Returns a string representation of the object. In general, the
     * {@code toString} method returns a string that
     * "textually represents" this object. The result should
     * be a concise but informative representation that is easy for a
     * person to read.
     * It is recommended that all subclasses override this method.
     * <p>
     * The {@code toString} method for class {@code Object}
     * returns a string consisting of the name of the class of which the
     * object is an instance, the at-sign character `{@code @}\', and
     * the unsigned hexadecimal representation of the hash code of the
     * object. In other words, this method returns a string equal to the
     * value of:
     * <blockquote>
     * <pre>
     * getClass().getName() + \'@\' + Integer.toHexString(hashCode())
     * </pre></blockquote>
     *
     * @return a string representation of the object.
     */
    @Override
    public String toString(){
        return super.toString() + " name:" + this.name + " ATK:" + this.ATK + " attackDistance:" + attackDistance;
    }
}
Weapon

2、备忘录角色,用于保存原始角色需要记录的状态信息

/*
 * Copyright (c) 2017. Xiaomi.Co.Ltd All rights reserved
 */

package com.pt.memo;

/**
 * @description 游戏者备忘录
 * @author panteng
 * @date 17-2-24.
 */
public class Memotor {
    public Integer HP;
    public Weapon weapon;

    public Memotor(){
    }

    public Memotor(Integer HP, Weapon weapon){
        this.HP = HP;
        this.weapon = weapon;
    }

    public Integer getHP(){
        return HP;
    }
    public void setHP(Integer HP){
        this.HP = HP;
    }
    public Weapon getWeapon(){
        return weapon;
    }
    public void setWeapon(Weapon weapon){
        this.weapon = weapon;
    }
}
Memotor

3、备忘录管理者角色,主要做好封装,防止备忘录被修改

/*
 * Copyright (c) 2017. panteng.Co.Ltd All rights reserved
 */

package com.pt.memo;

/**
 * @description 备忘录管理者,之所以有此角色,是保护备忘录不被改变,备忘录模式使用上,除管理者和发起者外,其他不可以操作备忘录;
 * @author panteng
 * @date 17-2-24.
 */
public class MemotorManager {
    Memotor memotor;

    public MemotorManager(Memotor memotor){
        this.memotor = memotor;
    }

    public Memotor getMemotor(){
        return memotor;
    }
    public void setMemotor(Memotor memotor){
        this.memotor = memotor;
    }
}

4、测试类

/*
 * Copyright (c) 2017. Xiaomi.Co.Ltd All rights reserved
 */

package com.pt.memo;

import org.junit.Test;

/**
 * @description
 * @author panteng
 * @date 17-2-24.
 */
public class MemotorTest {
    @Test
    public void memotoeTest() throws Exception{
        //创建一个两个武器
        Weapon weapon1 = new Weapon("手枪", 200.1F, 100.5F);
        Weapon weapon2 = new Weapon("狙击枪", 1000.25F, 200.5F);
        //创建一个游戏角色
        Player player = new Player("魂斗罗", 1000, weapon1);
        player.showState();
        //战斗前先备份
        MemotorManager memotorManager = new MemotorManager(player.createMemotor());
        MemotorManager memotorManager1 = new MemotorManager(player.createMemotorByDeepCopy());
        System.out.println("战斗... ... 切换武器... ...");
        player.setWeapon(weapon2);  //切换武器
        player.setHP(0);            //挂了
        player.showState();
        //恢复
        System.out.println("恢复战斗前的状态... ...");
        player.recover(memotorManager.getMemotor());
        player.showState();
        //假如战斗过程中角色发生了这样的变化
        System.out.println("==========================================================");
        player.setHP(1);
        player.getWeapon().setATK(0F);
        player.getWeapon().setAttackDistance(0F);
        player.showState();
        player.recover(memotorManager.getMemotor());
        player.showState(); //武器无法恢复,因为备份过程中采用的是浅复制,血量恢复了,说明Integer采用的是深复制
        //使用第二种方式恢复
        player.recover(memotorManager1.getMemotor());
        player.showState();
    }
}

 

 

===========================设计模式系列文章=========================

简单工厂模式

工厂方法模式

抽象工厂模式

建造者模式

原型模式

适配器模式

桥接模式

装饰模式

代理模式

组合模式

门面模式

享元模式

责任链模式

命令模式

中介者模式

备忘录模式

观察者模式

状态模式

策略模式

模板方法模式

访问者模式

以上是关于设计模式——备忘录模式的主要内容,如果未能解决你的问题,请参考以下文章

19-备忘录(Memento)模式Ruby实现

设计模式----备忘录模式

设计模式之备忘录模式

设计模式14:备忘录模式

设计模式之备忘录模式

设计模式之备忘录模式