zoukankan      html  css  js  c++  java
  • 设计模式之备忘录模式

    很多人都玩游戏,也知道游戏进度保存的重要性。一般我们在与boss决战之前就会保存自己角色的数据,万一被boss打得屁股尿流挂掉了,我们也可以从之前保存的进度重新开始。

    我们来程序模拟一下游戏进度的保存。

    第一版,简单的实现:

    public class GameRole {
        //生命力
        private int vit;
        //攻击力
        private int atk;
        //防御力
        private int def;
        public int getVit() {
            return vit;
        }
        public void setVit(int vit) {
            this.vit = vit;
        }
        public int getAtk() {
            return atk;
        }
        public void setAtk(int atk) {
            this.atk = atk;
        }
        public int getDef() {
            return def;
        }
        public void setDef(int def) {
            this.def = def;
        }
        //状态显示
        public void stateDisplay(){
            System.out.println("角色当前状态:");
            System.out.println("体力:" + this.vit);
            System.out.println("攻击力:" + this.atk);
            System.out.println("防御力:" + this.def);
        }
        //获得初始状态,数据通常来自本机磁盘或远程数据库
        public void getInitState(){
            this.vit = 100;
            this.atk = 100;
            this.def = 100;
        }
        //战斗,与boss大战后游戏数据损耗为零
        public void fight(){
            this.vit = 0;
            this.atk = 0;
            this.def = 0;
        }
    }
    public class Test {
    
        public static void main(String[] args) {
            // 大战前
            GameRole lixiaoyao = new GameRole();
            lixiaoyao.getInitState();
            lixiaoyao.stateDisplay();
            //保存进度
            System.out.println("----------------");
            GameRole backup = new GameRole();
            backup.setVit(lixiaoyao.getVit());
            backup.setAtk(lixiaoyao.getAtk());
            backup.setDef(lixiaoyao.getDef());
            //大战boss,损耗严重
            System.out.println("----------------");
            lixiaoyao.fight();
            lixiaoyao.stateDisplay();
            //恢复之前的状态
            System.out.println("----------------");
            lixiaoyao.setAtk(backup.getAtk());
            lixiaoyao.setDef(backup.getDef());
            lixiaoyao.setVit(backup.getVit());
            lixiaoyao.stateDisplay();
            
        }
    
    }

    代码无错未必优。这段代码的问题主要在于客户端的调用,这样写就是等于把整个游戏角色的细节暴露给了客户端,客户端的职责就太大了。需要知道生命力,攻击力,防御力的细节,还要对他进行备份等等。显然,我们希望把存取游戏进度的细节封装起来,而且最好封装在外部的类中,以体现职责分离。这里需要用到一个新的设计模式-备忘录模式。

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

    Memento模式比较适用于功能比较复杂的,但需要维护或记录属性历史的类,或需要保存的属性只是众多属性中的一部分时,Originator可以根据保存的Memento信息还原到之前的状态。比如在某个系统使用命令模式时,需要实现命令的撤销功能,那么命令模式可以使用备忘录模式来存储可撤销的操作状态。

    第二版,游戏进度备忘

    public class GameRole1 {
        //生命力
        private int vit;
        //攻击力
        private int atk;
        //防御力
        private int def;
        public int getVit() {
            return vit;
        }
        public void setVit(int vit) {
            this.vit = vit;
        }
        public int getAtk() {
            return atk;
        }
        public void setAtk(int atk) {
            this.atk = atk;
        }
        public int getDef() {
            return def;
        }
        public void setDef(int def) {
            this.def = def;
        }
        //保存角色状态
        public RoleStateMemoto saveState(){
            return new RoleStateMemoto(vit,atk,def);
        }
        //恢复角色状态
        public void recoveryState(RoleStateMemoto memoto){
            this.vit = memoto.getVit();
            this.atk = memoto.getDef();
            this.def = memoto.getDef();
        }
        //状态显示
            public void stateDisplay(){
                System.out.println("角色当前状态:");
                System.out.println("体力:" + this.vit);
                System.out.println("攻击力:" + this.atk);
                System.out.println("防御力:" + this.def);
            }
            //获得初始状态,数据通常来自本机磁盘或远程数据库
            public void getInitState(){
                this.vit = 100;
                this.atk = 100;
                this.def = 100;
            }
            //战斗,与boss大战后游戏数据损耗为零
            public void fight(){
                this.vit = 0;
                this.atk = 0;
                this.def = 0;
            }
    }
    public class RoleStateMemoto {
        //生命力
            private int vit;
            //攻击力
            private int atk;
            //防御力
            private int def;
            public RoleStateMemoto(int vit, int atk, int def){
                this.vit = vit;
                this.atk = atk;
                this.def = def;
            }
            public int getVit() {
                return vit;
            }
            public void setVit(int vit) {
                this.vit = vit;
            }
            public int getAtk() {
                return atk;
            }
            public void setAtk(int atk) {
                this.atk = atk;
            }
            public int getDef() {
                return def;
            }
            public void setDef(int def) {
                this.def = def;
            }
    }
    public class RoleStateCareTaker {
        private RoleStateMemoto memoto;
    
        public RoleStateMemoto getMemoto() {
            return memoto;
        }
    
        public void setMemoto(RoleStateMemoto memoto) {
            this.memoto = memoto;
        }
    }
    public class Test2 {
    
        public static void main(String[] args) {
            //大战boss前
            GameRole1 lixiaoyao = new GameRole1();
            lixiaoyao.getInitState();
            lixiaoyao.stateDisplay();
            
            //保存进度
            RoleStateCareTaker stateAdmin = new RoleStateCareTaker();
            stateAdmin.setMemoto(lixiaoyao.saveState());
            
            //大战boss时,损耗严重
            lixiaoyao.fight();
            lixiaoyao.stateDisplay();
            
            //恢复之前的状态
            lixiaoyao.recoveryState(stateAdmin.getMemoto());
            lixiaoyao.stateDisplay();
            
        }
    
    }
  • 相关阅读:
    java基础测试
    java随笔
    Android 开机广播的使用
    ZOJ 3715 Kindergarten Election
    LightOJ 1051
    LightOJ 1042
    LightOJ 1049
    LightOJ 1048
    LeightOJ 1046
    LightOJ 1045
  • 原文地址:https://www.cnblogs.com/shicaiyou/p/9353450.html
Copyright © 2011-2022 走看看