测试类
package com.jsxs.behavioralModel.memento.white_box; /** * @Author Jsxs * @Date 2023/4/24 19:51 * @PackageName:com.jsxs.behavioralModel.memento.white_box * @ClassName: Client * @Description: TODO * @Version 1.0 */ public class Client { public static void main(String[] args) { System.out.println("----------大战boss前------------"); //创建游戏角色 GameRole gameRole = new GameRole(); //初始化游戏角色 gameRole.initState(); //展示初始化后的游戏状态 gameRole.stateDisplay(); // 将该游戏角色内部状态进行备份 //创建管理者对象 RoleStateCaretaker roleStateCaretaker = new RoleStateCaretaker(); roleStateCaretaker.setRoleStateMemento(gameRole.saveState()); System.out.println("----------大战boss后------------"); // 损耗严重 gameRole.fight(); // 大战后状态演示 gameRole.stateDisplay(); // 恢复之前的状态 gameRole.recoverState(roleStateCaretaker.getRoleStateMemento()); // 恢复之后展示 gameRole.stateDisplay(); } }
- 黑箱模式
备忘录角色对发起人对象提供一个宽接口
,而为其它对象提供一个提供一个窄接口
。在Java语言中,实现双重接口的办法就是将备忘录类
设计成为发起人类的内部成员类。
将RoleStateMemento
设为GameRole
的内部类,从而将RoleStateMento
对象封装在GameRloe
里面;在外面提供一个标识接口Memento
给RoleStateCaretaker
及其他对象使用。这样GameRole
类看到的是RoleStateMemento
所有的接口,而RoleStateCaretaker
及其他对象看到的仅仅是标识接口Memento
所有暴露出来的接口,从而维护了封装型。
备忘录接口
package com.jsxs.behavioralModel.memento.black_box; /** * @Author Jsxs * @Date 2023/4/24 20:32 * @PackageName:com.jsxs.behavioralModel.memento.black_box * @ClassName: Menento * @Description: TODO 备忘录接口,对外提供窄接口 * @Version 1.0 */ public interface Menento { }
package com.jsxs.behavioralModel.memento.black_box; /** * @Author Jsxs * @Date 2023/4/24 19:39 * @PackageName:com.jsxs.behavioralModel.memento.white_box * @ClassName: GanmeRole * @Description: TODO 游戏角色类 (发起人角色) * @Version 1.0 */ public class GameRole { private int vit; //生命力 private int atk; //攻击力 private int def; //防御力 // 初始化状态的方法 public void initState(){ this.vit=100; this.atk=100; this.def=100; } // 战斗后的方法 public void fight(){ this.vit=0; this.atk=0; this.def=0; } // 保存角色状态功能 public Menento saveState(){ return new RoleStateMemento(vit,atk,def); } // 恢复角色状态功能 public void recoverState(Menento memento){ RoleStateMemento roleStateMemento=(RoleStateMemento) memento; // 将备忘录中存储的状态赋值给当前对象的成员 this.atk=roleStateMemento.getAtk(); this.vit=roleStateMemento.getVit(); this.def=roleStateMemento.getDef(); } //展示状态功能 public void stateDisplay(){ System.out.println("角色生命力:"+vit); System.out.println("角色攻击力:"+atk); System.out.println("角色防御力:"+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; } private class RoleStateMemento implements Menento{ private int vit; //生命力 private int atk; //攻击力 private int def; //防御力 public RoleStateMemento(int vit, int atk, int def) { this.vit = vit; this.atk = atk; this.def = def; } public RoleStateMemento() { } 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; } } }
测试
package com.jsxs.behavioralModel.memento.black_box; /** * @Author Jsxs * @Date 2023/4/24 19:51 * @PackageName:com.jsxs.behavioralModel.memento.white_box * @ClassName: Client * @Description: TODO * @Version 1.0 */ public class Client { public static void main(String[] args) { System.out.println("----------大战boss前------------"); //创建游戏角色 GameRole gameRole = new GameRole(); //初始化游戏角色 gameRole.initState(); //展示初始化后的游戏状态 gameRole.stateDisplay(); // 将该游戏角色内部状态进行备份 //创建管理者对象 RoleStateCaretaker roleStateCaretaker = new RoleStateCaretaker(); roleStateCaretaker.setMemento(gameRole.saveState()); System.out.println("----------大战boss后------------"); // 损耗严重 gameRole.fight(); // 大战后状态演示 gameRole.stateDisplay(); // 恢复之前的状态 gameRole.recoverState(roleStateCaretaker.getMemento()); // 恢复之后展示 gameRole.stateDisplay(); } }
(4).优缺点
优点:
- 提供了一种可以恢复状态的机制。当用户需要时能够比较方便地将数据恢复到某个历史地状态。
- 实现了内部状态地封装。除了创建它地发起人之外,其他对象都不能够访问这些状态信息。
- 简化了发起人类,发起人不需要管理和把偶你其他内部状态信息过多或者特别频繁,将会占比比较大地内存资源。
缺点:
- 资源消耗大。如果要保存地内部状态信息过多或者特别频繁,将会占用比较大地内存资源。
使用场景:
- 需要保存与恢复数据地场景,如玩游戏时地中间结果地存放功能。
- 需要提供一个可回滚地场景,如 word、记事本、等软件地ctrl+z
11.解释器模式
(1).概述
设计一个软件用来进行加减计算。我们第一想法就是使用工具类,提供对应地加法和减法地工具方法
定义: 给定一个语言,它定义地文法标识,并定义一个解释想起,这个解释器使用该标识来解释语言中地句子
。
(2).结构
- 抽象表达式角色: 定义
解释器地接口
,约定解释器地解释操作,主要包含解释方法 interpret(), - 终结符表达角色: 是抽象表达式地子类,用来实现文法中与中介符相关地操作,文法中地每一个终结符都有一个具体中介表达式与之相对应。
- 非总结符表达式角色:也是抽象表达式地子类,用来实现文法中与非终结符相关地操作,文法中地每条规则都对应一个非终结符表达式。
- 环境角色:通常包含各个解释器需要地数据或是公共地功能,一般用俩传递被所有解释器共享地数据,后面地解释器可以从这里获取这些值。
- 客户端: 主要任务是将需要分析地句子或表达式转换成使用解释器对象描述地抽象语法树,然后调用解释器地解释方法,当然也可以通过环境角色简介访问解释器地解释方法。
(3).优缺点
优点:
- 易于改变和扩展文法:
- 实现文法较为容易: 代码编写不会特别复杂
- 增加新地解释表达式较为方便: 符合开闭原则
缺点:
- 对于复杂文法难以维护
- 执行效率较低
使用场景:
- 当语言的文法较为简单,且自信效率不是关键问题
- 当问题重复出现,且可以用一种简单的语言来进行表达时
- 当一个语言需要解释执行,并且语言中的句子可以标识为一个抽象语法树的时候。