Java 撤销/重做和命令委托
作为序言,这是我的第一个图书馆,而有点令人尴尬的是我的第一个博客文章😱。任何反馈将不胜感激!所有必须从某个地方开始吗?
当拖延我的学位时,我意识到我的最终项目包含一些有用的命令委托代码,这些代码可以组成一个不错的小图书馆。事不宜迟,让我介绍一下...
试剂名称
对于自述文件(也位于下面)和代码,请检出:
背景
该库起初是另一个项目的撤消/重做控制器,并由我本人和犯罪分子Matt进行了改编,作为我们在GitHub上进行协作的一部分。
该产品必须做三件事:
- 简化命令委托
- 简化撤销/重做
- 尽可能松散耦合
那么,命令委托是什么意思?
假设您有一个打开文件的程序,并为您提供了两个不同的编辑器窗口。每个编辑器窗口显然都有其自己的控制器,但是文件操作很可能在它们之间共享。在我们的案例中,编辑者并不特别在意文件的打开方式,只是不会被遗忘……
editor.populate(text)会很好地完成它们。
A
FileMenuController会知道您何时要打开文件,但是我们也希望我们的编辑者也知道,但是我们不一定希望控制器知道编辑器。这是我们的命令委托人进来的地方。
编辑者将订阅命令委托人,说他们想了解某些事件,在这种情况下为
FileOpenCommand。当文件控制器打开文件时,它将
FileOpenCommand向委托人发布一个文件,其中包含打开文件所需的任何信息。命令委托者将把此命令转发给编辑器,他们将担心命令的执行。
成功的代表团😄,但我们尚未完成...
撤销重做
正如以前实现过撤消/重做系统的任何人都会知道的那样,最棘手的方面可能是还原状态。为了能够撤消某个动作,您需要以RESTful方式工作的方法(无论状态如何都具有相同的行为),或者您需要存储要返回的状态。
身为宽宏的开发人员,我们决定不在乎,您应该能够做自己想做的事情。是的,自由!因此,撤消/重做过程使用四个实体:委托者、发布者、命令和执行者。命令可能包含状态,也可能不包含状态,但它们始终与执行器紧密耦合。
- 委托者:手柄执行订阅,并绕过呼吁
DO
、UNDO
以及REDO
对命令的执行者 - 发布者:向委托人发送命令的任何内容
- 命令:基本上是一个数据包,可能具有执行者要使用的实用方法
- 执行程序:控制命令的“完成”方式,可以选择执行撤消和重做
那么我该如何安装呢?
只需将其添加为对Maven的依赖!(涵盖了永远出色的Jenkov教程)
[code]<span style="color:#f8f8f2"><span style="color:#eff0f9"><code><span style="color:#f9690e"><dependency></span> <span style="color:#f9690e"><groupId></span>com.logdyn<span style="color:#f9690e"></groupId></span> <span style="color:#f9690e"><artifactId></span>re-agent<span style="color:#f9690e"></artifactId></span> <span style="color:#f9690e"><version></span>1.2<span style="color:#f9690e"></version></span> <span style="color:#f9690e"></dependency></span> </code></span></span>
那么我该如何使用呢?
我很懒,所以这直接来自自述文件,但是我很想提出改进建议👍
指令
该
Command接口的实现 用于触发subscription中的事件
Executor。
Command并未指定执行行为,而是用于触发事件并捕获该事件所需的任何信息。
[code]<span style="color:#f8f8f2"><span style="color:#eff0f9"><code><span style="color:#f39c12">class</span> <span style="color:#7ed07e">ExampleCommand</span> <span style="color:#f39c12">implements</span> <span style="color:#f8f8f2">UndoableCommand</span> <span style="color:#f9690e">{</span> <span style="color:#7ed07e">@Override</span> <span style="color:#f39c12">public</span> <span style="color:#f8f8f2">String</span> <span style="color:#7ed07e">getName</span><span style="color:#f9690e">()</span> <span style="color:#f9690e">{</span> <span style="color:#f39c12">return</span> <span style="color:#f2ca27">"Example Undoable Command"</span><span style="color:#f9690e">;</span> <span style="color:#f9690e">}</span> <span style="color:#f9690e">}</span> </code></span></span>
还有UndoableCommand,它可以被任何执行器执行,尽管如果你想使用undo/redo,必须使用UndoableExecutor。默认情况下,reexecute()方法调用execute(),不过可以覆盖它。UndoableCommand必须提供撤消操作以及初始执行所需的数据。
执行器
Executor接口的实现用于
Command在发布a后执行特定行为。
[code]<span style="color:#f8f8f2"><span style="color:#eff0f9"><code><span style="color:#f39c12">class</span> <span style="color:#7ed07e">ExampleExecutor</span> <span style="color:#f39c12">implements</span> <span style="color:#f8f8f2">UndoableExecutor</span><span style="color:#f9690e"><</span><span style="color:#f8f8f2">ExampleCommand</span><span style="color:#f9690e">></span> <span style="color:#f9690e">{</span> <span style="color:#7ed07e">@Override</span> <span style="color:#f39c12">public</span> <span style="color:#f39c12">void</span> <span style="color:#7ed07e">execute</span><span style="color:#f9690e">(</span><span style="color:#f8f8f2">ExampleCommand</span> <span style="color:#f8f8f2">command</span><span style="color:#f9690e">)</span> <span style="color:#f9690e">{</span> <span style="color:#f8f8f2">System</span><span style="color:#f9690e">.</span><span style="color:#7ed07e">out</span><span style="color:#f9690e">.</span><span style="color:#7ed07e">println</span><span style="color:#f9690e">(</span><span style="color:#f2ca27">"Hello, World!"</span><span style="color:#f9690e">);</span> <span style="color:#f9690e">}</span> <span style="color:#7ed07e">@Override</span> <span style="color:#f39c12">public</span> <span style="color:#f39c12">void</span> <span style="color:#7ed07e">unexecute</span><span style="color:#f9690e">(</span><span style="color:#f8f8f2">ExampleCommand</span> <span style="color:#f8f8f2">command</span><span style="color:#f9690e">)</span> <span style="color:#f9690e">{</span> <span style="color:#f8f8f2">System</span><span style="color:#f9690e">.</span><span style="color:#7ed07e">out</span><span style="color:#f9690e">.</span><span style="color:#7ed07e">println</span><span style="color:#f9690e">(</span><span style="color:#f2ca27">"Goodbye, World!"</span><span style="color:#f9690e">);</span> <span style="color:#f9690e">}</span> <span style="color:#7ed07e">@Override</span> <span style="color:#f39c12">public</span> <span style="color:#f39c12">void</span> <span style="color:#7ed07e">reexecute</span><span style="color:#f9690e">(</span><span style="color:#f8f8f2">ExampleCommand</span> <span style="color:#f8f8f2">command</span><span style="color:#f9690e">)</span> <span style="color:#f9690e">{</span> <span style="color:#f8f8f2">System</span><span style="color:#f9690e">.</span><span style="color:#7ed07e">out</span><span style="color:#f9690e">.</span><span style="color:#7ed07e">println</span><span style="color:#f9690e">(</span><span style="color:#f2ca27">"Hello again, World!"</span><span style="color:#f9690e">);</span> <span style="color:#f9690e">}</span> <span style="color:#f9690e">}</span> </code></span></span>
订阅命令
订阅a
Command要求您指定an
Executor和
Command它将执行。一个
Executor将要执行的类型
Command是订阅,或任何亚类的那个
Command。结果,仅
Executor此类型或的子类型之一
Command。
[code]<span style="color:#f8f8f2"><span style="color:#eff0f9"><code><span style="color:#f8f8f2">CommandDelegator</span><span style="color:#f9690e">.</span><span style="color:#7ed07e">getINSTANCE</span><span style="color:#f9690e">().</span><span style="color:#7ed07e">subscribe</span><span style="color:#f9690e">(</span><span style="color:#f39c12">new</span> <span style="color:#f8f8f2">ExampleExecutor</span><span style="color:#f9690e">(),</span> <span style="color:#f8f8f2">ExampleCommand</span><span style="color:#f9690e">.</span><span style="color:#7ed07e">class</span><span style="color:#f9690e">);</span> </code></span></span>
发布(
Doing)命令
发布a
Command就像将其传递给
publish()方法一样简单。然后将调用
execute()相关
Executor类的方法。对的调用
execute()将与对的调用在同一线程上
publish,这意味着,如果要启动任务以在后台运行,则必须从后台发布该任务。
如果发布的
Command内容不可撤消,它将清除当前的撤消历史记录。同样,如果您撤消了a
Command并发布了新的a ,则将清除重做历史记录。
[code]<span style="color:#f8f8f2"><span style="color:#eff0f9"><code><span style="color:#f8f8f2">CommandDelegator</span><span style="color:#f9690e">.</span><span style="color:#7ed07e">getINSTANCE</span><span style="color:#f9690e">().</span><span style="color:#7ed07e">publish</span><span style="color:#f9690e">(</span><span style="color:#f39c12">new</span> <span style="color:#f8f8f2">ExampleCommand</span><span style="color:#f9690e">());</span> </code></span></span>
撤销重做
撤消和重做是上的方法调用
CommandDelegator。此操作与方法相同
publish(),将调用相关类的
unexecute()or
reexecute()方法
Executor。
[code]<span style="color:#f8f8f2"><span style="color:#eff0f9"><code><span style="color:#f8f8f2">CommandDelegator</span><span style="color:#f9690e">.</span><span style="color:#7ed07e">getINSTANCE</span><span style="color:#f9690e">().</span><span style="color:#7ed07e">undo</span><span style="color:#f9690e">();</span> <span style="color:#f8f8f2">CommandDelegator</span><span style="color:#f9690e">.</span><span style="color:#7ed07e">getINSTANCE</span><span style="color:#f9690e">().</span><span style="color:#7ed07e">redo</span><span style="color:#f9690e">();</span> </code></span></span>
全做完了!
原文链接:https://dev.to//jsjlewis96/introducing-re-agent-java-undoredo--command-delegation-56n3
cunxiedian8614 原创文章 0获赞 2访问量 2万+ 关注 私信- 【编程模式】(一) ------ 命令模式 和 “重做” 及 “撤销”
- 命令模式+备忘录模式,实现可撤销重做的计算器
- 【GOF23设计模式】_命令模式_数据库事务机制底层架构实现_撤销和回复JAVA246
- 关于命令模式个人的理解 撤销 重做的实现
- JAVA 必会的Linux 命令
- Java设计模式之命令模式
- 【总结】java命令解析以及编译器,虚拟机如何定位类
- java调用dos命令
- java设计模式之命令模式
- java调用linux命令传递参数问题
- JAVA设计模式之命令模式
- git撤销命令
- java 命令notes
- java 从指定行读文件,执行系统命令
- java执行几条unix命令,并将执行结果追加到文件
- java与javac命令的功用
- 仿net事件委托的java事件模型实现
- linux的shell命令检测某个java程序是否执行
- java命令编译时
- Java 开发必会的 Linux 命令