【搞懂设计模式】命令模式:从遥控器到编程的妙用!

简介: 【搞懂设计模式】命令模式:从遥控器到编程的妙用!

我们都熟悉电视遥控器,它有许多按钮,每个按钮都有确定的功能。你按下电源键电视就会打开,再按下一次电视就会关闭。编程世界里也有这种模式,这就是我们说的命令模式。

命令模式是一种设计模式它把一个请求或操作封装到一个对象中。这意味着命令模式允许我们将操作分开,我们可以控制何时和如何执行它们

遥控你的代码:命令模式的编程实战

了解命令模式的最好方式,就是通过代码来看看它如何运作。

假设我们要制作一个游戏模拟器,运行器可以执行两个命令,启动和关闭

// 游戏模拟器操作接口
interface Command {
    void execute();
}

class GameConsole {
    public void start_game() {
        System.out.println("游戏开启!");
    }

    public void stop_game() {
        System.out.println("游戏关闭!");
    }
}

// 启动命令
class StartCommand implements Command {
    GameConsole console;

    public StartCommand(GameConsole console) {
        this.console = console;
    }

    public void execute() {
        console.start_game();
    }
}

// 停止命令
class StopCommand implements Command {
    GameConsole console;

    public StopCommand(GameConsole console) {
        this.console = console;
    }

    public void execute() {
        console.stop_game();
    }
}

// 游戏模拟器
class GameSimulator {
    HashMap<String, Command> commands = new HashMap<>();

    public void register(String cmd_name, Command command) {
        commands.put(cmd_name, command);
    }

    public void execute(String cmd_name) {
        if (commands.containsKey(cmd_name)) {
            Command command = commands.get(cmd_name);
            command.execute();
        } else {
            System.out.println("Unknown command!");
        }
    }
}

public class Main {
    public static void main(String[] args) {
        GameSimulator simulator = new GameSimulator();
        GameConsole console = new GameConsole();
        simulator.register("START", new StartCommand(console));
        simulator.register("STOP", new StopCommand(console));

        simulator.execute("START");
        simulator.execute("STOP");
    }
}

在上面的Java代码中,我们创建了一个游戏模拟器,它可以执行两种命令:启动和停止。我们使用了接口来定义Command,它只有一个execute方法。然后,我们创建了两个Command的实现类,即启动命令(StartCommand)和停止命令(StopCommand)。

命令模式如何实现撤销/恢复?

撤销和恢复的操作是通过以下两步实现的:

  1. 每次执行命令时,将该命令对象存储在历史记录列表中(如stack)
  2. 撤销操作其实就是从历史记录中取出最近的命令,并执行它的反操作。如果该命令对象中包含了执行前对象的状态信息,则撤销操作可以通过恢复这些状态来实现

让我们来看一个Java代码例子,这个例子展示了如何使用命令模式实现撤销功能:

interface Command {
    void execute();
    void undo();
}

class AddTextCommand implements Command {
    private String textToAdd;
    private TextEditor editor;

    public AddTextCommand(String textToAdd, TextEditor editor) {
        this.textToAdd = textToAdd;
        this.editor = editor;
    }

    public void execute() {
        editor.addText(textToAdd);
    }

    public void undo() {
        editor.removeText(textToAdd);
    }
}

class TextEditor {
    private StringBuilder text = new StringBuilder();

    public void addText(String textToAdd) {
        text.append(textToAdd);
    }

    public void removeText(String textToRemove) {
        int index = text.lastIndexOf(textToRemove);
        if (index != -1) {
            text.delete(index, index + textToRemove.length());
        }
    }

    public void printText() {
        System.out.println(text.toString());
    }
}

class TextEditorDriver {
    private Stack<Command> commandHistory = new Stack<>();

    public void executeCommand(Command cmd) {
        cmd.execute();
        commandHistory.push(cmd);
    }

    public void undoLastCommand() {
        if (!commandHistory.isEmpty()) {
            Command lastCmd = commandHistory.pop();
            lastCmd.undo();
        }
    }
}

在这段代码中,我们首先定义了一个Command接口,并添加了一个新的方法undo。我们的每个具体命令都必须定义这两个方法。


在TextEditorDriver类中,我们维护了一个命令历史stack。每次执行命令时,我们都将命令添加到这个stack中。当我们要撤销操作时,我们只需取出最新的命令,并调用它的undo方法。


在命令模式中,撤销和恢复功能的实现核心是在每个具体的命令中,都保存了足够的信息以便在需要时可以反转其效果。通过使用存储的命令历史,我们不仅可以撤销命令,还可以重做它们。

命令模式的深入理解

以上的小例子虽然简单,但是已经显示了命令模式的三大优点

  • 解耦调用者与接收者:命令模式可以解耐调用者和接收者之间的耦合,将一个请求封装为一个对象,使发出请求的责任和执行请求的责任分割开。
  • 命令可扩展:你可以增加新的命令而完全不改变现有的代码。
  • 支持撤销、队列、宏命令等:命令模式的另一个优点就是可以后期扩展新的特性。比如可以添加命令历史来实现撤销和恢复等功能,或者搭建任务队列进行后台处理等。

命令模式是创建型和行为型设计模式的交织,使用它,你就可以变得像使用遥控器一样自由自在地控制你的代码。

命令模式是创建型和行为型设计模式的交织怎么理解?

我们之前提到命令模式是创建型和行为型设计模式的交织。那么这句话是怎么理解的呢?

设计模式通常被分为三种类型:创建型,结构型和行为型。

  1. 创建型模式:这类模式主要处理对象创建机制,尝试在创建对象的过程中增加更多的灵活性和效率。简单工厂、抽象工厂、建造者、原型、单例等都是创建型模式。
  2. 结构型模式:这类模式主要关注对象组合,或者换句话说,实体之间如何互相使用。这些模式能保证系统中各部分之间相互关系的清晰地定义。适配器、桥接、组合、装饰、外观、享元、代理等都是结构型模式。
  3. 行为型模式:这类模式专注于对象间的通信,它们的主要目的是增强对象间的通信以及如何控制复杂系统中多个对象的协作。策略、模板方法、观察者、迭代器、责任链、命令、备忘录、状态、访问者等都是行为型模式。

命令模式是一个行为型模式,因为它解决的主要问题是将行为请求者和接收者进行解耦,实现请求的封装。这让请求者不必知道接收者的接口,也不必知道请求是怎么被接收的,以及操作是否被执行、是如何执行的,等等。

不过,命令模式也涉及创建型模式的一些特性:它涉及到具体命令类的创建以及如何和特定接收者实例相关联。每个具体的命令类都封装了特定的行为和调用接收者的相应方法。这样,每个命令可以看作是一个完整的操作


因此,命令模式是创建型模式和行为型模式的交织。它是创建型的,因为它创建了具有特定行为的命令对象。同时它是行为型的,因为这些对象被调用来执行特定的行为。

总结

理解和从实际角度看待设计模式非常重要,因为它们是我们进行有效编程和设计灵活可维护系统的工具。希望这次的讨论能帮助你更好地理解命令模式,明白它是如何综合创建型模式和行为型模式的。


当然,设计模式并不是银弹,应当根据具体场景和需求采取合适的设计模式。而这个能力则需要大量实践和经验的积累,加油!


如果上面的内容对你有帮助,请点赞收藏哦,我会分享更多的经验~

相关文章
|
18天前
|
设计模式 开发者 Python
Python编程中的设计模式:工厂方法模式###
本文深入浅出地探讨了Python编程中的一种重要设计模式——工厂方法模式。通过具体案例和代码示例,我们将了解工厂方法模式的定义、应用场景、实现步骤以及其优势与潜在缺点。无论你是Python新手还是有经验的开发者,都能从本文中获得关于如何在实际项目中有效应用工厂方法模式的启发。 ###
|
3月前
|
设计模式 数据库连接 PHP
PHP编程中的面向对象与设计模式
在PHP编程世界中,掌握面向对象编程(OOP)和设计模式是提升代码质量和开发效率的关键。本文将深入浅出地介绍如何在PHP中应用OOP原则和设计模式,以及这些实践如何影响项目架构和维护性。通过实际案例,我们将探索如何利用这些概念来构建更健壮、可扩展的应用程序。
|
6天前
|
设计模式 算法 搜索推荐
Python编程中的设计模式:优雅解决复杂问题的钥匙####
本文将探讨Python编程中几种核心设计模式的应用实例与优势,不涉及具体代码示例,而是聚焦于每种模式背后的设计理念、适用场景及其如何促进代码的可维护性和扩展性。通过理解这些设计模式,开发者可以更加高效地构建软件系统,实现代码复用,提升项目质量。 ####
|
20天前
|
设计模式 监控 数据库连接
Python编程中的设计模式之美:提升代码质量与可维护性####
【10月更文挑战第21天】 一段简短而富有启发性的开头,引出文章的核心价值所在。 在编程的世界里,设计模式如同建筑师手中的蓝图,为软件的设计和实现提供了一套经过验证的解决方案。本文将深入浅出地探讨Python编程中几种常见的设计模式,通过实例展示它们如何帮助我们构建更加灵活、可扩展且易于维护的代码。 ####
|
28天前
|
设计模式 开发者 Python
Python编程中的设计模式:从入门到精通####
【10月更文挑战第14天】 本文旨在为Python开发者提供一个关于设计模式的全面指南,通过深入浅出的方式解析常见的设计模式,帮助读者在实际项目中灵活运用这些模式以提升代码质量和可维护性。文章首先概述了设计模式的基本概念和重要性,接着逐一介绍了几种常用的设计模式,并通过具体的Python代码示例展示了它们的实际应用。无论您是Python初学者还是经验丰富的开发者,都能从本文中获得有价值的见解和实用的技巧。 ####
|
25天前
|
设计模式 开发者 Python
Python编程中的设计模式应用与实践###
【10月更文挑战第18天】 本文深入探讨了Python编程中设计模式的应用与实践,通过简洁明了的语言和生动的实例,揭示了设计模式在提升代码可维护性、可扩展性和重用性方面的关键作用。文章首先概述了设计模式的基本概念和重要性,随后详细解析了几种常用的设计模式,如单例模式、工厂模式、观察者模式等,在Python中的具体实现方式,并通过对比分析,展示了设计模式如何优化代码结构,增强系统的灵活性和健壮性。此外,文章还提供了实用的建议和最佳实践,帮助读者在实际项目中有效运用设计模式。 ###
14 0
|
28天前
|
设计模式 存储 数据库连接
Python编程中的设计模式之美:单例模式的妙用与实现###
本文将深入浅出地探讨Python编程中的一种重要设计模式——单例模式。通过生动的比喻、清晰的逻辑和实用的代码示例,让读者轻松理解单例模式的核心概念、应用场景及如何在Python中高效实现。无论是初学者还是有经验的开发者,都能从中获得启发,提升对设计模式的理解和应用能力。 ###
|
2月前
|
设计模式 安全 Java
Java 编程中的设计模式:单例模式的深度解析
【9月更文挑战第22天】在Java的世界里,单例模式就像是一位老练的舞者,轻盈地穿梭在对象创建的舞台上。它确保了一个类仅有一个实例,并提供全局访问点。这不仅仅是代码优雅的体现,更是资源管理的高手。我们将一起探索单例模式的奥秘,从基础实现到高级应用,再到它与现代Java版本的舞蹈,让我们揭开单例模式的面纱,一探究竟。
40 11
|
2月前
|
设计模式 存储 算法
Java设计模式-命令模式(16)
Java设计模式-命令模式(16)
|
3月前
|
设计模式 算法 安全
Java编程中的设计模式:提升代码的可维护性和扩展性
【8月更文挑战第19天】在软件开发的世界里,设计模式是解决常见问题的一种优雅方式。本文将深入探讨Java编程语言中常用的几种设计模式,并解释如何通过这些模式来提高代码的可维护性和扩展性。文章不涉及具体的代码实现,而是侧重于理论和实践相结合的方式,为读者提供一种思考和改善现有项目的新视角。

热门文章

最新文章

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