- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
所以我有一个程序,您可以在其中登录并在 friends
数组列表中添加/删除 friend 。我也可以喜欢某个东西,那个东西将被存储到 likes
arraylist 中。我被要求为我执行的任何操作设置撤消和重做选项。
所以我想加apple为好友。之后,当我选择撤消选项时,我可以撤消该操作,这样 apple 就不会成为我的 friend 。当输入是我输入要存储到 friends
数组列表中的任何名称或单词时,我如何使用 Command Pattern
来解决这个问题?
我做了一些研究,发现使用命令模式可能是我最好的选择,因为这必须在我已有的 Facebook 类下完成。我假设我将不得不使用两个不同的堆栈,但我有点迷失了主题。
我决定添加我已有的部分内容,以便在我需要做什么以及我的程序做什么方面获得更多帮助。
在驱动程序中
Facebook facebook1 = new Facebook();
if (userInput == 6)
{
System.out.println("Login");
String operand1 = getOperand("What is the Username? ");
String operand2 = getOperand("What is the Password? ");
System.out.println("Enter a friend to be added. ");
String operand3 = getOperand("What is the Username? ");
facebook1.friend(operand3);
}
if (userInput == 7)
{
System.out.println("Login");
String operand1 = getOperand("What is the Username? ");
String operand2 = getOperand("What is the Password? ");
System.out.println("Enter a friend to be removed. ");
String operand3 = getOperand("What is the Username? ");
facebook1.defriend(operand3);
}
if (userInput == 12)
{
System.out.println("Login");
String operand1 = getOperand("What is the Password? ");
facebook1.undo();
}
if (userInput == 13)
{
System.out.println("Login");
String operand1 = getOperand("What is the Password? ");
facebook1.redo();
}
在 Facebook 类里面
ArrayList<FacebookUser> recommendedFriends = new ArrayList<FacebookUser>();
void friend(String newFriend)
{
boolean positiveChecker = false;
for (int i = 0; i < recommendedFriends.size(); i++)
{
if (recommendedFriends.get(i).toString().equalsIgnoreCase(newFriend))
{
System.out.println("Error: This friend already exists.");
positiveChecker = true;
}
}
if (positiveChecker == false)
{
FacebookUser friend = new FacebookUser(newFriend, newFriend );
recommendedFriends.add(friend);
System.out.println(friend + " is now your friend.");
}
positiveChecker = false;
}
void defriend(String formerFriend)
{
boolean positiveChecker = false;
for (int i = 0; i < recommendedFriends.size(); i++)
{
if (recommendedFriends.get(i).toString().equalsIgnoreCase(formerFriend))
{
recommendedFriends.remove(i);
System.out.println(formerFriend + " has been removed from your friends list.");
positiveChecker = true;
}
if (recommendedFriends.size() == (i + 1) && recommendedFriends.get(i).toString() != formerFriend
&& positiveChecker == false)
{
System.out.println("Error: There is no friend with this username.");
}
}
positiveChecker = false;
}
public interface Command
{
public void undo();
public void redo();
}
最佳答案
当你撤消 2 件事然后做一个全新的 Action 时,你需要“忘记”“重做历史”并用新命令替换它,对吧?
例如……
State 应该是“Jim”和“Bill”。
所以你真的只需要一个列表和一个指向当前“命令”的指针,例如......
// Note: NOT thread safe!
public class CommandStack {
private List<Command> commands = Collections.emptyList();
private int nextPointer = 0;
public void doCommand(Command command) {
List<Command> newList = new ArrayList<>(nextPointer + 1)
for(int k = 0; k < nextPointer; k++) {
newList.add(commands.get(k));
}
newList.add(command);
commands = newList;
nextPointer++;
// Do the command here, or return it to whatever called this to be done, or maybe it has already been done by now or something
// (I can only guess on what your code currently looks like...)
command.execute();
}
public boolean canUndo() {
return nextPointer > 0;
}
public void undo() {
if(canUndo()) {
nextPointer--;
Command commandToUndo = commands.get(nextPointer);
// Undo the command, or return it to whatever called this to be undone, or something
command.undo();
} else {
throw new IllegalStateExcpetion("Cannot undo");
}
}
public boolean canRedo() {
return nextPointer < commands.size();
}
public void redo() {
if(canRedo()) {
commandToDo = commands.get(nextPointer);
nextPointer++;
// Do the command, or return it to whatever called this to be re-done, or something
commandToDo.execute();
} else {
throw new IllegalStateException("Cannot redo");
}
}
}
如果我有...
interface Command { /* execute / undo etc */ }
public class AddFriendCommand implements Command {
private String friendName;
// ... other fields, constructor / getters etc ...
public void execute() {
// Actually do it...
System.out.println("Added friend " + name);
}
public void undo() {
// Undo it...
System.out.println("Removed friend " + name);
}
}
public class RemoveFriendCommand implements Command {
private String friendName;
// ... other fields, constructor / getters etc ...
public void execute() {
// Actually do it, maybe throw exception if friend does not exist?
// (that would have to be a runtime exception unless you want the interface's method to throw stuff);
System.out.println("Removed friend " + name);
}
public void undo() {
// Undo it...
System.out.println("Added friend " + name);
}
}
您可以使用...重复上面的序列
CommandStack stack = new CommandStack();
stack.doCommand(new AddFriendCommand("Jim"));
stack.doCommand(new AddFriendCommand("Bill"));
stack.doCommand(new AddFriendCommand("Jill"));
stack.doCommand(new RemoveFreindCommand("Jim"));
stack.undo();
stack.undo();
如果您现在执行了一个新命令(通过 doCommand),它会忘记您曾经添加过“Jill”或删除过“Jim”,而是现在会记住新命令和未撤消的其余命令历史记录。
希望这对您有所帮助。
关于java - 在 ArrayLists 中使用命令模式进行撤消和重做,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29660504/
关闭。这个问题是off-topic .它目前不接受答案。 想改进这个问题吗? Update the question所以它是on-topic用于堆栈溢出。 关闭 9 年前。 Improve this
我有一系列 SQL 命令,我想在大约 40 个不同的表上运行。必须有一种方法可以在不编写 40 条不同命令的情况下执行此操作... 我在 SQL Server 中运行它。所有表都有不同的名称,我要操作
我习惯在 PHP 中使用命令“mysql_insert_id()”来返回插入到我的数据库中的最后一行的 id。 在 C# 中的 SQLite 中是否有等效的命令? 谢谢! -阿德娜 最佳答案 选择 l
试图找出一种方法来回填 ds 分区 Hive 表的分区。 我知道如何从 CLI 运行 Hive 命令,例如 $HIVE_HOME/bin/hive -e 'select a.col from tab1
我有 .bat 文件。看起来像下一个 ....many commands1 ftp -i -s:copy.txt ...many commands2 copy.txt 包含下一个命令 open ...
基本上我想输入 show 并检查是否有 show 命令或别名已定义并触发它,如果未定义则触发 git show 。 例如 rm 应该执行 rm 但 checkout 应该执行 git checkout
我公司的主数据库是 iSeries 机器,我已经非常习惯使用 DB2 命令和结构。我现在正在尝试做一个小项目,更新一个包含超过 300 万条记录的表。我想出一种比较和“清理”数据的更快方法是使用 My
我想在带有 Node 的终端中制作一个简单的按钮板,并“blessed”用于连接或运行不同的命令。 ----------------------------------------------- _
我们有一个 selenium IDE 脚本,正在转换为 python webdriver。以下命令未转换: [openWindow | http://mywebsite.com/index.php |
我正在学习这个关于从 GIT HUB 下载和安装 Web 文件的在线教程。我进入主题:启动我们的静态网站,系统提示我输入命令以下载和安装 Web 文件。但是,当我输入命令 yarn install 时
我在 shell 脚本中使用 elif 命令时遇到问题,就像在 fortran 中一样。 我有 100 家公司的员工名单。我想屏蔽那些员工少于 500 人的公司。我的脚本是 rm -f categor
我有一些 Linux 命令可以生成 token 。我在 Linux 机器上使用操作系统库形式的 Python 自动化了这些命令。它工作正常。 但是,当我在 Windows 中尝试相同的代码时,它没有返
本文分享自华为云社区《Git你有可能不知道交互式暂存》,作者:龙哥手记。 本节中的几个交互式 Git 命令可以帮助你将文件的特定部分组合成提交。 当你在修改了大量文件后,希望这些改动能拆分为若干提交而
我想知道如何使用 IN 比较语法来做到这一点。 当前的 SQL 查询是: select * from employee where (employeeName = 'AJAY' and month(e
我在这个位置安装了 Hadoop /usr/local/hadoop$ 现在我想列出 dfs 中的文件。我使用的命令是: hduser@ubuntu:/usr/local/hadoop$ bin/ha
是否有一个单一的 docker 命令可用于清除所有内容?如果正在运行,请停止所有容器、删除所有图像、删除所有卷...等。 最佳答案 我认为没有一个命令可以做到这一点。您首先需要停止所有容器使用 $ d
我基本上是在 clojure/nrepl 模式中寻找与 C-u C-x C-e 或 C-c C-p 等效的 Scheme。 我想要一个 C-x C-e 将输出打印到缓冲区,而不是仅仅在 repl 中。
我可以在 vim 中使用 pudb(一个 ncurses Python 调试器),因为,例如,:!python %在实际的终端窗口中运行。我更喜欢使用 gvim,但 gvim 运行 :!python
我正在尝试编写一个 FFMPEG 命令: 取为 输入 一个视频 input.mp4 和一个图像 pic.jpg 作为 输出 将 input.mp4 拆分为 20 秒的视频,按顺序重命名;对于每个分割视
我想转储视频每帧的比特率。我正在尝试使用 -vstats 获取此信息命令。当我运行此命令时 - ffmpeg -i input.mp4 -vstats 它显示至少应该定义一个文件。 如果有人能建议我任
我是一名优秀的程序员,十分优秀!