首页 文章 精选 留言 我的

精选列表

搜索[Java],共10000篇文章
优秀的个人博客,低调大师

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

优秀的个人博客,低调大师

Java描述设计模式(23):访问者模式

本文源码:GitHub·点这里 || GitEE·点这里 一、生活场景 1、场景描述 电竞是游戏比赛达到“竞技”层面的体育项目。利用电子设备作为运动器械进行的、人与人之间的智力对抗运动。通过电竞,可以提高人的反应能力、协调能力、团队精神等。但是不同人群的对电竞的持有的观念不一样,有的人认为电竞就是沉迷网络,持反对态度,而有的人就比较赞同。下面基于访问者模式来描述该场景。 2、场景图解 3、代码实现 public class C01_InScene { public static void main(String[] args) { DataSet dataSet = new DataSet() ; dataSet.addCrowd(new Youth()); dataSet.addCrowd(new MiddleAge()); CrowdView crowdView = new Against() ; dataSet.display(crowdView); crowdView = new Approve() ; dataSet.display(crowdView); } } /** * 双分派,不同人群管理 */ abstract class Crowd { abstract void accept(CrowdView action); } class Youth extends Crowd { @Override public void accept(CrowdView view) { view.getYouthView(this); } } class MiddleAge extends Crowd { @Override public void accept(CrowdView view) { view.getMiddleAgeView (this); } } /** * 不同人群观念的管理 */ abstract class CrowdView { // 青年人观念 abstract void getYouthView (Youth youth); // 中年人观念 abstract void getMiddleAgeView (MiddleAge middleAge); } class Approve extends CrowdView { @Override public void getYouthView(Youth youth) { System.out.println("青年人赞同电竞"); } @Override public void getMiddleAgeView(MiddleAge middleAge) { System.out.println("中年人赞同电竞"); } } class Against extends CrowdView { @Override public void getYouthView(Youth youth) { System.out.println("青年人反对电竞"); } @Override public void getMiddleAgeView(MiddleAge middleAge) { System.out.println("中年人反对电竞"); } } /** * 提供一个数据集合 */ class DataSet { private List<Crowd> crowdList = new ArrayList<>(); public void addCrowd (Crowd crowd) { crowdList.add(crowd); } public void display(CrowdView crowdView) { for(Crowd crowd : crowdList) { crowd.accept(crowdView); } } } 二、访问者模式 1、基础概念 访问者模式是对象的行为模式,把作用于数据结构的各元素的操作封装,操作之间没有关联。可以在不改变数据结构的前提下定义作用于这些元素的不同的操作。主要将数据结构与数据操作分离,解决数据结构和操作耦合问题核心原理:被访问的类里面加对外提供接待访问者的接口。 2、模式图解 3、核心角色 抽象访问者角色 声明多个方法操作,具体访问者角色需要实现的接口。 具体访问者角色 实现抽象访问者所声明的接口,就是各个访问操作。 抽象节点角色 声明接受操作,接受访问者对象作为参数。 具体节点角色 实现抽象节点所规定的具体操作。 结构对象角色 能枚举结构中的所有元素,可以提供一个高层的接口,用来允许访问者对象访问每一个元素。 4、源码实现 public class C02_Visitor { public static void main(String[] args) { ObjectStructure obs = new ObjectStructure(); obs.add(new NodeA()); obs.add(new NodeB()); Visitor visitor = new VisitorA(); obs.doAccept(visitor); } } /** * 抽象访问者角色 */ interface Visitor { /** * NodeA的访问操作 */ void visit(NodeA node); /** * NodeB的访问操作 */ void visit(NodeB node); } /** * 具体访问者角色 */ class VisitorA implements Visitor { @Override public void visit(NodeA node) { node.operationA() ; } @Override public void visit(NodeB node) { node.operationB() ; } } class VisitorB implements Visitor { @Override public void visit(NodeA node) { node.operationA() ; } @Override public void visit(NodeB node) { node.operationB() ; } } /** * 抽象节点角色 */ abstract class Node { /** * 接收访问者 */ abstract void accept(Visitor visitor); } /** * 具体节点角色 */ class NodeA extends Node{ @Override public void accept(Visitor visitor) { visitor.visit(this); } public void operationA(){ System.out.println("NodeA.operationA"); } } class NodeB extends Node{ @Override public void accept(Visitor visitor) { visitor.visit(this); } public void operationB(){ System.out.println("NodeB.operationB"); } } /** * 结构对象角色类 */ class ObjectStructure { private List<Node> nodes = new ArrayList<>(); public void detach(Node node) { nodes.remove(node); } public void add(Node node){ nodes.add(node); } public void doAccept(Visitor visitor){ for(Node node : nodes) { node.accept(visitor); } } } 三、Spring框架应用 1、Bean结构的访问 BeanDefinitionVisitor类,遍历bean的各个属性;接口 BeanDefinition,定义Bean的各样信息,比如属性值、构造方法、参数等等。这里封装操作bean结构的相关方法,但却没有改变bean的结构。 2、核心代码块 public class BeanDefinitionVisitor { public void visitBeanDefinition(BeanDefinition beanDefinition) { this.visitParentName(beanDefinition); this.visitBeanClassName(beanDefinition); this.visitFactoryBeanName(beanDefinition); this.visitFactoryMethodName(beanDefinition); this.visitScope(beanDefinition); if (beanDefinition.hasPropertyValues()) { this.visitPropertyValues(beanDefinition.getPropertyValues()); } if (beanDefinition.hasConstructorArgumentValues()) { ConstructorArgumentValues cas = beanDefinition.getConstructorArgumentValues(); this.visitIndexedArgumentValues(cas.getIndexedArgumentValues()); this.visitGenericArgumentValues(cas.getGenericArgumentValues()); } } } 四、模式总结 1、优点描述 (1) 访问者模式符合单一职责原则、使程序具有良好的扩展性、灵活性; (2) 访问者模式适用与拦截器与过滤器等常见功能,数据结构相对稳定的场景; 2、缺点描述 (1) 访问者关注其他类的内部细节,依赖性强,违反迪米特法则,这样导致具体元素更新麻烦; (2) 访问者依赖具体元素,不是抽象元素,面向细节编程,违背依赖倒转原则; 五、源代码地址 GitHub·地址 https://github.com/cicadasmile/model-arithmetic-parent GitEE·地址 https://gitee.com/cicadasmile/model-arithmetic-parent

优秀的个人博客,低调大师

spider-flow 0.2.1 发布,Java 开源爬虫平台

spider-flow 是一个无需写代码的爬虫平台,通过定义流程的方式制定爬虫 2019年度最受欢迎中国开源软件评选,投一票给 spider-flow 吧,谢谢! 更新日志 新增selectOne方法,执行后返回Map对象 新增selectInt方法,执行后返回int 修复表达式在xxx${expr}格式中,expr为null时整个表达式返回null的问题 修复延迟计算不准确的问题 优化表达式null.方法/属性,以及map[null]、array[null]直接返回null 优化日志显示方式,提升性能 优化全局变量支持表达式语法 优化SQL支持表达式语法 演示站点 文档地址

优秀的个人博客,低调大师

spider-flow 0.2.0 发布,Java 开源爬虫平台

spider-flow 是一个无需写代码的爬虫平台,通过定义流程的方式制定爬虫 更新日志 新增全局变量功能 新增爬虫搜索功能 新增List打乱函数 新增内置demo(爬取开源中国动弹) 修复等待节点在双重循环中表现与预期不一致的BUG 修复某些Header无法设置的问题 修复循环次数可能不对的BUG 优化表格输出样式与高亮显示 优化表格输出tab页签名 演示站点 文档地址

优秀的个人博客,低调大师

spider-flow 0.1.0 发布,Java 开源爬虫平台

历时三个多月,第一个正式版发布 spider-flow 是一个无需写代码的爬虫平台,通过定义流程的方式制定爬虫 现已有特性如下: 支持css选择器、正则提取 支持JSON/XML格式 支持Xpath/JsonPath提取 支持多数据源、SQL select/insert/update/delete/批量插入 支持爬取JS动态渲染的页面 支持代理 支持二进制格式、二进制流格式 支持保存/读取文件(csv、xls、jpg等) 常用字符串、日期、文件、加解密等函数 支持流程嵌套 支持插件扩展(自定义执行器,自定义函数) 支持HTTP接口 已有插件如下: selenium 插件 redis 插件 mongodb 插件 IP代理池 插件 OCR 识别插件 OSS 插件 电子邮箱 插件 部分截图:

资源下载

更多资源
腾讯云软件源

腾讯云软件源

为解决软件依赖安装时官方源访问速度慢的问题,腾讯云为一些软件搭建了缓存服务。您可以通过使用腾讯云软件源站来提升依赖包的安装速度。为了方便用户自由搭建服务架构,目前腾讯云软件源站支持公网访问和内网访问。

Nacos

Nacos

Nacos /nɑ:kəʊs/ 是 Dynamic Naming and Configuration Service 的首字母简称,一个易于构建 AI Agent 应用的动态服务发现、配置管理和AI智能体管理平台。Nacos 致力于帮助您发现、配置和管理微服务及AI智能体应用。Nacos 提供了一组简单易用的特性集,帮助您快速实现动态服务发现、服务配置、服务元数据、流量管理。Nacos 帮助您更敏捷和容易地构建、交付和管理微服务平台。

Rocky Linux

Rocky Linux

Rocky Linux(中文名:洛基)是由Gregory Kurtzer于2020年12月发起的企业级Linux发行版,作为CentOS稳定版停止维护后与RHEL(Red Hat Enterprise Linux)完全兼容的开源替代方案,由社区拥有并管理,支持x86_64、aarch64等架构。其通过重新编译RHEL源代码提供长期稳定性,采用模块化包装和SELinux安全架构,默认包含GNOME桌面环境及XFS文件系统,支持十年生命周期更新。

WebStorm

WebStorm

WebStorm 是jetbrains公司旗下一款JavaScript 开发工具。目前已经被广大中国JS开发者誉为“Web前端开发神器”、“最强大的HTML5编辑器”、“最智能的JavaScript IDE”等。与IntelliJ IDEA同源,继承了IntelliJ IDEA强大的JS部分的功能。

用户登录
用户注册