Java描述设计模式(24):备忘录模式
本文源码:GitHub·点这里 || GitEE·点这里
一、生活场景
1、场景描述
常见的视频播放软件都具备这样一个功能:假设在播放视频西游记,如果这时候切换播放视频红楼梦,当再次切回播放西游记时,视频会从上次切走的时间点继续播放。下面基于备忘录设计模式来描述该场景流程。
2、场景图解
3、代码实现
public class C01_InScene { public static void main(String[] args) { Record record = new Record() ; Player player = new Player() ; PlayData pd1 = new PlayData("西游记","19:19") ; PlayData pd2 = new PlayData("红楼梦","29:19") ; player.setPlayData(pd1); player.saveProgress() ; System.out.println("正在播放:"+ player.getPlayData().getVideoName()+":"+ player.getPlayData().getPlayTime()); record.put(new Progress(pd1)); System.out.println("===切换播放视频==="); player.setPlayData(pd2); player.saveProgress() ; System.out.println("正在播放:"+ player.getPlayData().getVideoName()+":"+ player.getPlayData().getPlayTime()); record.put(new Progress(pd1)); System.out.println("===切回上个视频==="); player.resumeProgress(record.get(pd1.getVideoName())); System.out.println("正在播放:"+ player.getPlayData().getVideoName()+":"+ player.getPlayData().getPlayTime()); } } /** * 视频播放器 */ class Player { private PlayData playData ; public PlayData getPlayData() { return playData; } public void setPlayData(PlayData playData) { this.playData = playData; } public Progress saveProgress (){ return new Progress(playData) ; } public void resumeProgress (Progress progress){ playData = progress.getPlayData() ; } } /** * 播放进度 */ class Progress { private PlayData playData ; public Progress (PlayData playData){ this.playData = playData ; } public PlayData getPlayData() { return playData ; } } /** * 播放记录 */ class Record { private Map<String,Progress> dataMap = new HashMap<>() ; public void put (Progress progress){ dataMap.put(progress.getPlayData().getVideoName(),progress) ; } public Progress get (String videoName){ return dataMap.get(videoName) ; } } /** * 播放状态描述 */ class PlayData { private String videoName ; private String playTime ; public PlayData(String videoName, String playTime) { this.videoName = videoName; this.playTime = playTime; } public String getVideoName() { return videoName; } public void setVideoName(String videoName) { this.videoName = videoName; } public String getPlayTime() { return playTime; } public void setPlayTime(String playTime) { this.playTime = playTime; } }
执行效果:
正在播放:西游记:19:19 ===切换播放视频=== 正在播放:红楼梦:29:19 ===切回上个视频=== 正在播放:西游记:19:19
二、备忘录模式
1、基础概念
备忘录模式属于行为型模式,其用意在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。后续可将该对象恢复到原先保存的状态。备忘录对象主要用来记录一个对象的某种状态,或者某些数据,当要做回退时,可以从备忘录对象里获取原来的数据进行恢复操作。
2、模式图解
3、核心角色
- 备忘录角色
负责保存对象状态的记录,即Originator内部状态。
- 发起人角色
创建一个含有当前的内部状态的备忘录对象,用来保存状态。
- 守护者对象
提供合理的方式,负责保存多个备忘录对象。
4、源码实现
public class C02_Memento { public static void main(String[] args) { Originator originator = new Originator(); Caretaker caretaker = new Caretaker(); originator.setState("状态1:State01"); caretaker.add(originator.saveStateMemento()); originator.setState("状态2:State02"); caretaker.add(originator.saveStateMemento()); System.out.println("当前的状态是 =" + originator.getState()); // 恢复状态 originator.getStateFromMemento(caretaker.get(0)); System.out.println("当前的状态是 =" + originator.getState()); } } /** * 守护者对象 */ class Caretaker { private List<Memento> mementoList = new ArrayList<>(); public void add(Memento memento) { mementoList.add(memento); } public Memento get (int index) { return mementoList.get(index); } } /** * 备忘录角色 */ class Memento { private String state; public Memento(String state) { super(); this.state = state; } public String getState() { return state; } } /** * 发起人角色 */ class Originator { private String state; public String getState() { return state; } public void setState(String state) { this.state = state; } public Memento saveStateMemento() { return new Memento(state); } public void getStateFromMemento(Memento memento) { state = memento.getState(); } }
三、模式总结
1、优缺点描述
备忘录模式提供一种可以恢复状态的机制,实现状态的封装,能够比较方便地回到某个历史的状态;常常与命令模式和迭代器模式一同使用。如果类的成员变量过多,会占用比较大的内存资源,为了节约内存,备忘录模式可以和原型模式配合使用。
2、应用场景
- 浏览器的前进和回退;
- 数据库备份与还原;
- 编辑器
Ctrl+Z
撤销; - 虚拟机生成快照与恢复;
- Git版本管理,代码的提交和回滚。
四、源代码地址
GitHub·地址 https://github.com/cicadasmile/model-arithmetic-parent GitEE·地址 https://gitee.com/cicadasmile/model-arithmetic-parent
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
OmniTool.NET开发包 - 用C#高效开发Omni/USDT区块链应用
OmniTool.Net开发包适用于为.Net/C#应用快速增加对Omni Layer/USDT数字资产的支持能力,即支持使用自有Omni Layer节点的应用场景,也支持基于第三方API服务和离线裸交易的轻量级部署场景。OmniTool.Net开发包官方下载地址:http://sc.hubwiz.com/codebag/omni-dotnet-lib/。 1、开发包概述 OmniTool.Net开发包主要包含以下特性: 完善的Omni Layer节点RPC API封装 支持利用自有节点或第三方服务获取指定地址的比特币utxo集合 支持离线生成omni代币转账裸交易 支持利用自有节点或第三方服务广播裸交易 OmniTool.Net支持本地部署的Omnicored节点,也支持第三方服务提供的开放API,要增加新的第三方服务也非常简单,只需要参考代码实现如下接口: IUtxoCollector:utxo收集器 IBroadcaster:裸交易广播器 OmniTool.Net软件包当前版本1.0.0,主要类/接口及关系如下图所示: OmniTool.Net软件包主要代码文件清单如下: 代码文...
- 下一篇
零代码一分钟创建 HTTP 服务(一)
一、背景 如果你想快速搭建一个 HTTP 服务来测试,以往可能需要用 Java/Node.js 等语言写个脚本部署到服务器上,但现在你多了一种完全无需写代码方案:阿里云逻辑编排。 借助逻辑编排,不要一行代码不到一分钟就可以实现 HTTP 服务。 二、实现 2.1 创建编排实例 首先进入逻辑编排控制台 https://lc.console.aliyun.com/flow,点击 “创建编排实例”: 2.2 图形化设计 创建成功后,会有个弹窗提示是否使用模板,默认不使用,我们也不需要使用,点击“确定” 直接进入到实例的图形化设计界面。 我们先不管这么多概念,直接操作。 2.2.1 接收 HTTP 请求 点击 “当收到 HTTP 请求时”,会进入下图的界面: 可以看到有几个属性: HTTP Endpointe:就是 HTTP 服务的 URL,保存后会自动生成。而我们自己编程实现 HTTP 服务,则需要我们自己绑定域名到部署代码的服务器上; Method:就是通过 GET 或 POST 方法来请求该 HTTP 服务 请求正文 JSON Schema:非必填项,先不管它 现在我们就使用默认配置,继...
相关文章
文章评论
共有0条评论来说两句吧...