首页 > 其他分享 >命令模式学习

命令模式学习

时间:2023-05-31 22:22:22浏览次数:36  
标签:start stringBuilder void 模式 学习 命令 回退 public

命令模式通过将请求封装成Command对象实现了请求的调用者和请求的执行者之间的解耦,并且可以很方便的实现请求排队,日志记录,命令撤销等操作。这里边比较经典的一个功能就是通过命令模式可以把已经执行的命令记录下来,轻松的实现命令的回退,重做这些操作,类似在文本编辑器中的操作。

命令模式通常有这么几个角色:命令接口,命令接口的具体实现,命令的接收者,命令的调用者

接下来我用命令模式来模拟一个文本编辑器来举例说明下,此文本编辑器支持回退功能

我把编辑器中可以进行的操作抽象成一个命令接口TextCommand,因为要支持回退,所以要让某个命令自己提供回退的功能。

package com.lyy.design.command_design.textEdit;

// 文本编辑命令接口,抽象出执行操作和回退两个方法
public interface TextCommand {
    //封装某个具体的编辑操作
    void execute();
    //当前编辑操作对应的回退功能
    void undo();
}

接下里我定义一个插入操作的具体命令实现,也就是命令的接收者

public class InsertTextCommand implements TextCommand{
    private StringBuilder stringBuilder;
    private int start;
    private String content;

    public InsertTextCommand(StringBuilder stringBuilder, int start, String content) {
        this.stringBuilder = stringBuilder;
        this.start = start;
        this.content = content;
    }

    @Override
    public void execute() {
        //执行插入
        this.stringBuilder.insert(start,content);
    }
    //回滚插入
    @Override
    public void undo() {
        this.stringBuilder.delete(start,start+content.length());
    }
}

然后再定义一个delete操作的具体命令实现,也是一个命令的接收者

public class DeleteTextCommand implements TextCommand{
    private StringBuilder stringBuilder;
    private int start;
    private int end;
    private String deleteContent;

    public DeleteTextCommand(StringBuilder stringBuilder, int start, int end) {
        this.stringBuilder = stringBuilder;
        this.start = start;
        this.end = end;
    }

    @Override
    public void execute() {
        //删除前要把被删除的内容存起来,后边回退要用
        this.deleteContent=stringBuilder.substring(start,end);
        //执行删除
        stringBuilder.delete(start,end);
    }

    @Override
    public void undo() {
        //执行回退
        stringBuilder.insert(start,deleteContent);
    }
}

然后再定义一个命令的调用者,像命令回退,日志记录这些功能其实都是通过命令调用者来具体实现的

import java.util.Stack;

public class TextCommandInvoker {
    //使用两个栈存储执行的命令
    private Stack<TextCommand> commandStack = new Stack<>();
    private Stack<TextCommand> undoCommandStack = new Stack<>();

    public void execute(TextCommand command) {
        command.execute();
        //编辑操作执行成功后把对应的命令存到commandStack中
        commandStack.push(command);
    }
    //回退刚刚进行的操作
    public void undo(){
        if(commandStack.isEmpty()) {
            return;
        }
        //从commandStack中取出刚刚执行过的命令
        TextCommand command = commandStack.pop();
        //执行此命令的回滚操作
        command.undo();
        //把刚刚回退的命令放到undoCommandStack,等待后续的redo操作使用
        undoCommandStack.push(command);
    }
    //重做刚刚被回退的命令
    public void redo(){
        if(undoCommandStack.isEmpty()) {
            return;
        }
        //从undoCommandStack中取出刚刚被回退的命令
        TextCommand command = undoCommandStack.pop();
        //重新执行此命令
        command.execute();
        //把重新执行的命令放到commandStack,等待后续undo时调用
        commandStack.push(command);
    }
}

然后测试下我们这个命令模式的代码

public class TextClient {
    public static void main(String[] args) {
        StringBuilder sb = new StringBuilder();
        TextCommandInvoker invoker = new TextCommandInvoker();
        invoker.execute(new InsertTextCommand(sb,0,"hello"));
        System.out.println("after insert:"+sb);
        invoker.execute(new DeleteTextCommand(sb,1,5));
        System.out.println("after delete:"+sb);
        invoker.undo();
        System.out.println("after undo:"+sb);
        invoker.redo();
        System.out.println("after redo:"+sb);
    }
}

控制台会得到这样的输入

after insert:hello
after delete:h
after undo:hello
after redo:h

符合我们设计的编辑器中的编辑,回退,重做功能设想。这就是命令模式的一个典型的例子。

标签:start,stringBuilder,void,模式,学习,命令,回退,public
From: https://www.cnblogs.com/chengxuxiaoyuan/p/17447504.html

相关文章

  • 英国皇家植物园采用机器学习预测植物抗疟性,将准确率从 0.46 提升至 0.67
    内容一览:疟疾是严重危害人类生命健康的重大传染病,研究人员一直在致力于寻找新的植物源性抗疟疾化合物,以研发相关药物。近期英国皇家植物园利用机器学习算法有效预测了植物抗疟性,该研究成果目前已发表在《FrontiersinPlantScience》期刊上。关键词:植物学抗疟疾支持向量......
  • 算法学习(22): 逆序对与原序列
    逆序对与原序列在《组合数学》中有这么一个从逆序列构建一个排列的过程……而刚好有一场考试有考了类似的问题,于是在此总结一下。目录逆序对与原序列逆序列逆序个数带修改问题逆序列假定我们有序列\(P\)是\(\{1,2,\cdots,n\}\)的一个排列。如果\(i<j\)并且\(p_......
  • 【博学谷学习记录】超强总结,用心分享 | spark知识点总结2
    【博学谷IT技术支持】Action动作算子reduce:通过func函数聚集RDD中的所有元素,这个功能必须是可交换且可并联的collect:在驱动程序中,以数组的形式返回数据集的所有元素count:返回RDD的元素个数first:返回RDD的第一个元素(类似于take(1))take:返回一个由数据集的前n个元......
  • NumPy学习6
    今天学习 NumPy位运算 12,NumPy位运算NumPy中提供了以下按位运算函数:numpy按位运算函数序号函数位运算符描述说明1bitwise_and&计算数组元素之间的按位与运算。2bitwise_or|计算数组元素之间的按位或运算。3invert~计算数组元素之间的按位取反运算。......
  • Less学习(一)less变量
    前言Less语言中变量的使用方式主要有以下几种:普通变量选择器变量属性名变量URL变量参考Less中变量的使用......
  • kubernetes(k8s)大白学习02:容器和docker基础、使用、架构学习
    一、什么是容器容器简介简单说:容器(container)就是计算机上的一个沙盒进程,它与计算机上的所有其它进程相隔离。这种隔离是怎么做到的呢?它利用了内核提供的namespace和cgroup这2种技术。这些技术能力在Linux中已经存在了很长时间。而Docker或容器技术致力于将这些功能更......
  • Linux base64命令
    Linux常用命令base64命令用于编码/解码文件或标准输入输出用例:[root@localhost~]#echotest|base64#加密dGVzdAo=[root@localhost~]#echodGVzdAo=|base64-d#解密test ......
  • 深度学习进阶篇[7]:Transformer模型长输入序列、广义注意力、FAVOR+快速注意力、蛋白质
    深度学习进阶篇[7]:Transformer模型长输入序列、广义注意力、FAVOR+快速注意力、蛋白质序列建模实操。基于Transformer模型在众多领域已取得卓越成果,包括自然语言、图像甚至是音乐。然而,Transformer架构一直以来为人所诟病的是其注意力模块的低效,即长度二次依赖限制问题。随着输入......
  • 授权码 + PKCE 模式|OIDC & OAuth2.0 认证协议最佳实践系列【03】
    在上一篇文章中,我们介绍了 OIDC 授权码模式(点击下方链接查看),本次我们将重点围绕授权码+PKCE模式(AuthorizationCodeWithPKCE)进行介绍,从而让你的系统快速具备接入用户认证的标准体系。OIDC&OAuth2.0认证协议最佳实践系列02-授权码模式(AuthorizationCode)接入Authing......
  • 算法学习day37贪心part06-738、968
    packageLeetCode.greedypart06;/***738.单调递增的数字*当且仅当每个相邻位数上的数字x和y满足x<=y时,我们称这个整数是单调递增的。*给定一个整数n,返回小于或等于n的最大数字,且数字呈单调递增。*示例:*输入:n=332*输出:299**/public......