【设计模式】用Java实现命令模式

简介: 命令模式(Command Pattern)是一种行为设计模式,它将请求封装为一个对象,从而使你可以使用不同的请求对客户端进行参数化。命令模式还支持请求的排队、记录日志、撤销操作等功能。

一.命令模式介绍与使用场景


命令模式(Command Pattern)是一种行为设计模式,它将请求封装为一个对象,从而使你可以使用不同的请求对客户端进行参数化。命令模式还支持请求的排队、记录日志、撤销操作等功能。


在命令模式中,通常包含以下角色:

1.命令接口(Command):定义执行命令的方法,可以是抽象类或接口。

2.具体命令类(Concrete Command):实现命令接口,封装了具体的请求和接收者,负责执行请求。3.接收者类(Receiver):执行实际的操作,命令对象将请求委托给接收者来执行。4.调用者类(Invoker):调用命令对象来执行请求,并负责命令的管理和控制。5.客户端(Client):创建具体的命令对象,并将其分配给调用者来执行。

命令模式应用场景:

1.当需要将请求发送者和请求接收者解耦时,可以使用命令模式。命令模式通过将请求封装为对象,使得发送者和接收者之间不直接交互,而是通过命令对象进行通信。

2.当需要支持请求的排队、记录日志、撤销操作等功能时,命令模式是一个有用的选择。通过将命令对象放入队列或者记录执行日志,可以实现请求的排队和日志记录;同时,可以使用命令对象的撤销方法来实现撤销操作。

3.当需要将一组操作作为一个整体来执行时,可以使用命令模式。命令模式将一系列操作封装为一个命令对象,可以通过执行该命令对象来一次性执行一系列操作。

4.当希望实现操作的回滚功能时,命令模式可以派上用场。通过在命令对象中添加撤销方法,可以实现对操作的撤销,从而实现回滚功能。

5.当需要在不同的上下文中参数化和传递请求时,可以使用命令模式。命令对象可以包含与特定上下文相关的参数,从而在不同的上下文中执行相同的命令。


需要注意的是,命令模式增加了类和对象的数量,可能会带来一定的复杂性。因此,在设计时需要权衡命令的复杂性和可维护性,避免过度使用命令模式。此外,对于简单的操作,直接调用方法可能更加简洁和直观,不一定需要使用命令模式。


二.命令模式实现


首先,我们定义命令接口 Command:

public interface Command {
    void execute();
}

然后,我们创建具体命令类 ConcreteCommand

public class ConcreteCommand implements Command {
    private Receiver receiver;
    public ConcreteCommand(Receiver receiver) {
        this.receiver = receiver;
    }
    public void execute() {
        receiver.action();
    }
}

接下来,我们创建接收者类 Receiver,负责执行具体的操作:

public class Receiver {
    public void action() {
        System.out.println("执行具体操作");
    }
}

最后,我们定义调用者类 Invoker,负责管理和控制命令对象:

public class Invoker {
    private Command command;
    public void setCommand(Command command) {
        this.command = command;
    }
    public void executeCommand() {
        command.execute();
    }
}

现在,我们可以在客户端中使用命令模式:

public class Client {
    public static void main(String[] args) {
        Receiver receiver = new Receiver();
        Command command = new ConcreteCommand(receiver);
        Invoker invoker = new Invoker();
        invoker.setCommand(command);
        invoker.executeCommand();
    }
}

在上面的示例中,我们创建了一个接收者对象 receiver 和一个具体命令对象 command,将具体命令对象传递给调用者对象 invoker。最后,调用者对象执行命令的 executeCommand() 方法来触发具体命令的执行。  


下面再来举一个在实际应用场景下的例子


假设我们正在开发一个文本编辑器应用程序,我们需要实现一些常见的编辑操作,例如剪切、复制和粘贴。这时,我们可以使用命令模式来封装这些操作,并通过命令对象来执行它们。


首先,我们定义命令接口 Command

public interface Command {
    void execute();
}

然后,我们创建具体命令类 CutCommandCopyCommandPasteCommand

public class CutCommand implements Command {
    private TextEditor editor;
    public CutCommand(TextEditor editor) {
        this.editor = editor;
    }
    public void execute() {
        editor.cut();
    }
}
public class CopyCommand implements Command {
    private TextEditor editor;
    public CopyCommand(TextEditor editor) {
        this.editor = editor;
    }
    public void execute() {
        editor.copy();
    }
}
public class PasteCommand implements Command {
    private TextEditor editor;
    public PasteCommand(TextEditor editor) {
        this.editor = editor;
    }
    public void execute() {
        editor.paste();
    }
}

接下来,我们创建接收者类 TextEditor,它负责执行具体的编辑操作:

public class TextEditor {
    public void cut() {
        System.out.println("执行剪切操作");
    }
    public void copy() {
        System.out.println("执行复制操作");
    }
    public void paste() {
        System.out.println("执行粘贴操作");
    }
}

最后,我们定义调用者类 Menu,负责管理和控制命令对象:

public class Menu {
    private Command cutCommand;
    private Command copyCommand;
    private Command pasteCommand;
    public Menu(Command cutCommand, Command copyCommand, Command pasteCommand) {
        this.cutCommand = cutCommand;
        this.copyCommand = copyCommand;
        this.pasteCommand = pasteCommand;
    }
    public void cut() {
        cutCommand.execute();
    }
    public void copy() {
        copyCommand.execute();
    }
    public void paste() {
        pasteCommand.execute();
    }
}

现在,我们可以在客户端中使用命令模式:

public class Client {
    public static void main(String[] args) {
        TextEditor editor = new TextEditor();
        Command cutCommand = new CutCommand(editor);
        Command copyCommand = new CopyCommand(editor);
        Command pasteCommand = new PasteCommand(editor);
        Menu menu = new Menu(cutCommand, copyCommand, pasteCommand);
        menu.cut();
        menu.copy();
        menu.paste();
    }
}

在上面的示例中,我们创建了一个文本编辑器对象 editor,并创建了具体命令对象 cutCommandcopyCommandpasteCommand将它们传递给调用者对象 menu。最后,通过调用调用者对象的方法来执行具体的命令操作。

相关实践学习
【涂鸦即艺术】基于云应用开发平台CAP部署AI实时生图绘板
【涂鸦即艺术】基于云应用开发平台CAP部署AI实时生图绘板
相关文章
|
2月前
|
设计模式 Java Spring
Java 设计模式之责任链模式:优雅处理请求的艺术
责任链模式通过构建处理者链,使请求沿链传递直至被处理,实现发送者与接收者的解耦。适用于审批流程、日志处理等多级处理场景,提升系统灵活性与可扩展性。
342 2
|
2月前
|
设计模式 网络协议 数据可视化
Java 设计模式之状态模式:让对象的行为随状态优雅变化
状态模式通过封装对象的状态,使行为随状态变化而改变。以订单为例,将待支付、已支付等状态独立成类,消除冗长条件判断,提升代码可维护性与扩展性,适用于状态多、转换复杂的场景。
364 0
|
4月前
|
设计模式 缓存 Java
Java设计模式(二):观察者模式与装饰器模式
本文深入讲解观察者模式与装饰器模式的核心概念及实现方式,涵盖从基础理论到实战应用的全面内容。观察者模式实现对象间松耦合通信,适用于事件通知机制;装饰器模式通过组合方式动态扩展对象功能,避免子类爆炸。文章通过Java示例展示两者在GUI、IO流、Web中间件等场景的应用,并提供常见陷阱与面试高频问题解析,助你写出灵活、可维护的代码。
|
2月前
|
设计模式 算法 搜索推荐
Java 设计模式之策略模式:灵活切换算法的艺术
策略模式通过封装不同算法并实现灵活切换,将算法与使用解耦。以支付为例,微信、支付宝等支付方式作为独立策略,购物车根据选择调用对应支付逻辑,提升代码可维护性与扩展性,避免冗长条件判断,符合开闭原则。
418 35
|
2月前
|
设计模式 消息中间件 传感器
Java 设计模式之观察者模式:构建松耦合的事件响应系统
观察者模式是Java中常用的行为型设计模式,用于构建松耦合的事件响应系统。当一个对象状态改变时,所有依赖它的观察者将自动收到通知并更新。该模式通过抽象耦合实现发布-订阅机制,广泛应用于GUI事件处理、消息通知、数据监控等场景,具有良好的可扩展性和维护性。
321 8
|
4月前
|
设计模式 安全 Java
Java设计模式(一):单例模式与工厂模式
本文详解单例模式与工厂模式的核心实现及应用,涵盖饿汉式、懒汉式、双重检查锁、工厂方法、抽象工厂等设计模式,并结合数据库连接池与支付系统实战案例,助你掌握设计模式精髓,提升代码专业性与可维护性。
|
4月前
|
设计模式 XML 安全
Java枚举(Enum)与设计模式应用
Java枚举不仅是类型安全的常量,还具备面向对象能力,可添加属性与方法,实现接口。通过枚举能优雅实现单例、策略、状态等设计模式,具备线程安全、序列化安全等特性,是编写高效、安全代码的利器。
|
设计模式 缓存 安全
Java设计模式的单例模式应用场景
Java设计模式的单例模式应用场景
305 4
|
设计模式 Java 数据库连接
Java编程中的设计模式:单例模式的深度剖析
【10月更文挑战第41天】本文深入探讨了Java中广泛使用的单例设计模式,旨在通过简明扼要的语言和实际示例,帮助读者理解其核心原理和应用。文章将介绍单例模式的重要性、实现方式以及在实际应用中如何优雅地处理多线程问题。
213 4
|
设计模式 安全 Java
Java 编程中的设计模式:单例模式的深度解析
【9月更文挑战第22天】在Java的世界里,单例模式就像是一位老练的舞者,轻盈地穿梭在对象创建的舞台上。它确保了一个类仅有一个实例,并提供全局访问点。这不仅仅是代码优雅的体现,更是资源管理的高手。我们将一起探索单例模式的奥秘,从基础实现到高级应用,再到它与现代Java版本的舞蹈,让我们揭开单例模式的面纱,一探究竟。
120 11