设计模式(十五) 命令模式

简介: 命令模式也是一种行为型模式,当我们的系统中需要处理各种命令(例如命令行)的时候,可以考虑使用命令模式,将命令封装为对象。这样和将命令直接硬编码到程序中相比,无疑是更好的。

命令模式也是一种行为型模式,当我们的系统中需要处理各种命令(例如命令行)的时候,可以考虑使用命令模式,将命令封装为对象。这样和将命令直接硬编码到程序中相比,无疑是更好的。

我们来做一个在线测评系统(OJ)的后端。我们需要检测一下当前后端有多少种可用的编译环境。检测方法很简单,就是使用各种编译环境的-version参数来查看一下版本,如果获取到版本号就说明当前编译环境是可用的。

首先,我们新建一个接口,作为检测接口。后面的命令对象都需要实现该接口。

public interface RequirementChecker {
    boolean isReady();
    String getInfo();
}

下一步就是讲命令行参数转换为命令对象了。为了简便,我这里创建了一个公共抽象父类,主要操作都放在了父类中。子类只需要简单的继承父类并传入命令行即可。关于Process类的使用方法,可以参考我的另一篇文章Java 调用外部程序。这里其实还隐含了一个调用契约,只有当isReady()方法返回真的时候,我们才能使用getInfo()方法获取版本号信息。

public abstract class AbstractCommand implements RequirementChecker {
    private ProcessBuilder processBuilder;
    private String info;
    private String encoding = "GBK";

    public AbstractCommand(String command) {
        processBuilder = new ProcessBuilder("cmd", "/C", command);
        processBuilder.redirectErrorStream(true);
    }

    @Override
    public boolean isReady() {
        Boolean result = false;
        try {
            Process process = processBuilder.start();
            process.waitFor();
            result = process.exitValue() == 0;
            if (result) {
                BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream(), encoding));
                info = reader.lines()
                        .collect(Collectors.joining("\n"));
            }
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return result;
    }

    @Override
    public String getInfo() {
        return info;
    }
}

最后来创建一些子类。这些子类只需要简单的继承父类,并传入需要的命令行即可。

class PythonCommand extends AbstractCommand {

    public PythonCommand() {
        super("python --version");
    }
}

class JavaCommand extends AbstractCommand {
    public JavaCommand() {
        super("java -version");
    }
}

class WindowsCommand extends AbstractCommand {
    public WindowsCommand() {
        super("ver");
    }
}

class BadCommand extends AbstractCommand {
    public BadCommand() {
        super("fuck");
    }
}

最后用例子来测试一下。如果电脑上安装有相应的开发环境或SDK,那么就会显示对应的版本信息。

    public void run() {
        RequirementChecker javaChecker = new JavaCommand();
        if (javaChecker.isReady()) {
            System.out.println(javaChecker.getInfo());
        }

        RequirementChecker pythonChecker = new PythonCommand();
        if (pythonChecker.isReady()) {
            System.out.println(pythonChecker.getInfo());
        }

        RequirementChecker windowsChecker = new WindowsCommand();
        if (windowsChecker.isReady()) {
            System.out.println(windowsChecker.getInfo());
        }

        RequirementChecker badChecker = new BadCommand();
        if (badChecker.isReady()) {
            System.out.println(badChecker.getInfo());
        }
    }
相关文章
|
6月前
|
设计模式 UED
二十三种设计模式:解锁软件开发的神器:命令模式与撤销重做功能
二十三种设计模式:解锁软件开发的神器:命令模式与撤销重做功能
156 0
|
2月前
|
设计模式 存储 算法
Java设计模式-命令模式(16)
Java设计模式-命令模式(16)
|
3月前
|
设计模式 存储 Java
【十二】设计模式~~~行为型模式~~~命令模式(Java)
文章详细介绍了命令模式(Command Pattern),这是一种对象行为型模式,用于将请求封装成对象,实现请求发送者与接收者的解耦,从而降低系统耦合度、提高灵活性,并支持命令的排队、记录、撤销和恢复操作。通过案例分析、结构图、时序图和代码示例,文章展示了命令模式的组成部分、实现方式和应用场景,并讨论了其优点、缺点和适用情况。
|
4月前
|
设计模式 JavaScript API
js设计模式【详解】—— 命令模式
js设计模式【详解】—— 命令模式
43 6
|
5月前
|
设计模式
命令模式-大话设计模式
命令模式-大话设计模式
|
5月前
|
设计模式 Java uml
必知的技术知识:JAVA【设计模式】命令模式
必知的技术知识:JAVA【设计模式】命令模式
27 0
|
5月前
|
设计模式 Java
Java设计模式之命令模式详解
Java设计模式之命令模式详解
|
5月前
|
设计模式
设计模式之命令模式
设计模式之命令模式
|
6月前
|
设计模式 Java 调度
【设计模式系列笔记】命令模式
命令模式是一种行为设计模式,它将请求封装成一个对象,从而允许使用不同的请求、队列或日志请求参数化客户端对象,同时支持撤销操作。
64 1
|
6月前
|
设计模式 Java 调度
小谈设计模式(24)—命令模式
小谈设计模式(24)—命令模式

热门文章

最新文章

  • 1
    《手把手教你》系列基础篇(九十四)-java+ selenium自动化测试-框架设计基础-POM设计模式实现-下篇(详解教程)
    44
  • 2
    C++一分钟之-C++中的设计模式:单例模式
    51
  • 3
    《手把手教你》系列基础篇(九十三)-java+ selenium自动化测试-框架设计基础-POM设计模式实现-上篇(详解教程)
    36
  • 4
    《手把手教你》系列基础篇(九十二)-java+ selenium自动化测试-框架设计基础-POM设计模式简介(详解教程)
    59
  • 5
    Java面试题:结合设计模式与并发工具包实现高效缓存;多线程与内存管理优化实践;并发框架与设计模式在复杂系统中的应用
    54
  • 6
    Java面试题:设计模式在并发编程中的创新应用,Java内存管理与多线程工具类的综合应用,Java并发工具包与并发框架的创新应用
    39
  • 7
    Java面试题:如何使用设计模式优化多线程环境下的资源管理?Java内存模型与并发工具类的协同工作,描述ForkJoinPool的工作机制,并解释其在并行计算中的优势。如何根据任务特性调整线程池参数
    49
  • 8
    Java面试题:请列举三种常用的设计模式,并分别给出在Java中的应用场景?请分析Java内存管理中的主要问题,并提出相应的优化策略?请简述Java多线程编程中的常见问题,并给出解决方案
    102
  • 9
    Java面试题:设计模式如单例模式、工厂模式、观察者模式等在多线程环境下线程安全问题,Java内存模型定义了线程如何与内存交互,包括原子性、可见性、有序性,并发框架提供了更高层次的并发任务处理能力
    74
  • 10
    Go语言设计模式:使用Option模式简化类的初始化
    71