您的位置:首页 > 健康 > 养生 > 廊坊网络推广优化公司_全国城乡建设证件查询_微信小程序开发_企业管理软件管理系统

廊坊网络推广优化公司_全国城乡建设证件查询_微信小程序开发_企业管理软件管理系统

2024/12/23 16:15:16 来源:https://blog.csdn.net/weixin_46619605/article/details/142856983  浏览:    关键词:廊坊网络推广优化公司_全国城乡建设证件查询_微信小程序开发_企业管理软件管理系统
廊坊网络推广优化公司_全国城乡建设证件查询_微信小程序开发_企业管理软件管理系统

命令模式(Command Pattern)是一种行为型设计模式,它将请求封装为一个对象,从而使得请求的发送者和接收者解耦。

一、命令模式的核心思想
命令模式的核心思想是将“请求”封装成为一个对象,从而使得我们可以用不同的请求对客户进行参数化,对请求排队或记录请求日志,以及支持可撤销的操作。每一个命令都是一个操作:请求的一方发出请求要求执行一个操作;接收的一方收到请求,并执行相应的操作。命令模式允许请求的一方和接收的一方独立开来,使得请求的一方不必知道接收请求的一方的接口,更不必知道请求如何被接收、操作是否被执行、何时被执行,以及是怎么被执行的。

二、命令模式的结构
在命令模式结构图中,通常包含以下几个角色:

  1. Command(抽象命令类):一般是一个抽象类或接口,在其中声明了用于执行请求的execute()等方法,通过这些方法可以调用请求接收者的相关操作。
  2. ConcreteCommand(具体命令类):抽象命令类的子类,实现了在抽象命令类中声明的方法。它对应具体的接收者对象,将接收者对象的动作绑定其中。
  3. Invoker(调用者):请求发送者,它通过命令对象来执行请求。一个调用者并不需要在设计时确定其接收者,因此它只与抽象命令类之间存在关联关系。
  4. Receiver(接收者):执行与请求相关的操作,它具体实现对请求的业务处理。
  5. Client(客户端):创建具体的命令对象,并且设置命令对象的接收者。这里的客户端并不是常规意义上的客户端,而是在组装命令对象和接收者,也可以将其称为装配者。

三、命令模式的实现

命令模式的实现通常涉及以下几个步骤:

  1. 定义一个抽象的Command接口,其中声明一个execute()方法。
  2. 具体的命令类(ConcreteCommand)实现这个execute()方法,将一个发送者(Invoker)的请求转换为一个或多个接收者(Receiver)的操作。
  3. 发送者(Invoker)并不知道接收者的具体实现,它只需要触发命令对象的execute()方法即可。

四、命令模式的应用场景

命令模式有广泛的应用场景,主要包括以下几种:

  1. 将各种请求以命令的形式加入到队列中,然后由相应的线程或进程逐个执行这些命令。
  2. 将一系列相关的操作封装成一个命令,要么全部执行成功,要么全部回滚。
  3. 通过保存历史命令,可以轻松地实现撤销和重做功能。
  4. 在执行命令的时候,可以同时将该命令记录到日志中,用于审计跟踪。
  5. 命令对象可以实现一个undo()方法,用于撤销之前执行的命令。
  6. 将多个命令组合成一个复合命令,可以一次性执行一系列操作。
  7. 在GUI程序中,可以使用命令模式来发出和处理用户点击按钮时表示的操作。
  8. 在多线程操作中,命令模式可以帮助程序在后台自动发出指令并处理其他业务,而不用等待线程完成操作。

五、命令模式的优点

  1. 降低了系统的耦合度:由于请求者与接收者之间通过命令对象进行交互,因此它们之间的依赖关系被解耦。
  2. 增强了系统的扩展性:新的命令可以很容易地添加到系统中,而不需要修改现有的客户端代码。
  3. 提供了命令的撤销和重做功能:通过保存历史命令,可以轻松地实现撤销和重做功能。
  4. 实现了请求的排队和日志记录:命令对象可以被存储在队列中,并在适当的时候执行。同时,也可以在执行命令的时候记录日志。

六、命令模式的缺点

  1. 增加了系统的复杂性:由于引入了抽象命令类、具体命令类、调用者和接收者等多个角色,系统的复杂性可能会增加。
  2. 可能会导致过度设计:如果系统中的命令数量并不多,或者命令的执行逻辑比较简单,那么使用命令模式可能会导致过度设计。

七、实战流程
不使用命令模式

public class Editor {public void copy() {// 复制逻辑}public void paste() {// 粘贴逻辑}public void undo() {// 撤销逻辑}
}public class User {public static void main(String[] args) {Editor editor = new Editor();editor.copy();editor.paste();editor.undo();}
}

使用命令模式优化

/*** 接收者*/
public class Editor {public void copy() {System.out.println("复制内容");}public void paste() {System.out.println("粘贴内容");}public void undo() {System.out.println("撤销操作");}
}/*** 命令接口*/
public interface Command {void execute();
}/*** 具体命令类*/
public class CopyCommand implements Command {private Editor editor;public CopyCommand(Editor editor) {this.editor = editor;}@Overridepublic void execute() {editor.copy();}
}public class PasteCommand implements Command {private Editor editor;public PasteCommand(Editor editor) {this.editor = editor;}@Overridepublic void execute() {editor.paste();}
}public class UndoCommand implements Command {private Editor editor;public UndoCommand(Editor editor) {this.editor = editor;}@Overridepublic void execute() {editor.undo();}
}/*** 调用者*/
public class Menu {private Command copyCommand;private Command pasteCommand;private Command undoCommand;public Menu(Command copyCommand, Command pasteCommand, Command undoCommand) {this.copyCommand = copyCommand;this.pasteCommand = pasteCommand;this.undoCommand = undoCommand;}public void clickCopy() {copyCommand.execute();}public void clickPaste() {pasteCommand.execute();}public void clickUndo() {undoCommand.execute();}
}public class CommandTest {public static void main(String[] args) {Editor editor = new Editor();Command copy = new CopyCommand(editor);Command paste = new PasteCommand(editor);Command undo = new UndoCommand(editor);Menu menu = new Menu(copy, paste, undo);menu.clickCopy();menu.clickPaste();menu.clickUndo();}
}

八、在JDK源码中应用命令模式的例子
1、java.lang.Runnable 和 java.util.concurrent.Callable

Runnable 和 Callable 接口是命令模式的典型例子。这两个接口封装了要在另一个线程中执行的任务,具体任务内容由 run() 方法或 call() 方法来实现,线程池或者线程的调用者在需要的时候执行这些任务。

(1)命令模式结构

  1. 命令接口:Runnable 和 Callable 是命令接口,定义了 run() 和 call() 方法,表示要执行的命令。
  2. 具体命令:任何实现 Runnable 或 Callable 的类都是具体命令类,封装了实际的任务逻辑。
  3. 调用者:Thread 或线程池(如 ExecutorService),负责触发命令的执行。

Runnable 的 run() 方法是命令的执行逻辑,而 Thread 是调用者,它负责在合适的时间触发 run() 的执行。

(2)代码示例

public class CommandExample {public static void main(String[] args) {// 创建一个命令(Runnable任务)Runnable command = new Runnable() {@Overridepublic void run() {System.out.println("执行命令: 线程中的任务");}};// 调用者:Thread 执行命令Thread thread = new Thread(command);thread.start();}
}

2、javax.swing.Action

在 Swing 框架中,Action 接口用于封装行为,它是典型的命令模式。Action 可以被 JButton、JMenuItem 等组件复用,从而将动作的定义与其使用解耦。

(1)命令模式结构

  • 命令接口:Action 接口。
  • 具体命令:实现 Action 接口的具体动作类,定义 actionPerformed(ActionEvent e) 方法,封装了执行逻辑。
  • 调用者:Swing 组件,如 JButton 或 JMenuItem,这些组件触发 Action 的执行。

(2)代码示例

sayHelloAction 是命令,JButton 是调用者,点击按钮会触发 actionPerformed 方法的执行。

import javax.swing.*;
import java.awt.event.ActionEvent;public class SwingCommandExample {public static void main(String[] args) {// 创建一个具体命令(Action)Action sayHelloAction = new AbstractAction("Say Hello") {@Overridepublic void actionPerformed(ActionEvent e) {System.out.println("Hello, World!");}};// 调用者:JButton,触发命令的执行JButton button = new JButton(sayHelloAction);// 创建一个简单的Swing窗口JFrame frame = new JFrame("Command Pattern Example");frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);frame.add(button);frame.pack();frame.setVisible(true);}
}

3、java.util.Timer 和 java.util.TimerTask

TimerTask 是 JDK 中另一个典型的命令模式实现。TimerTask 类实现了 Runnable 接口,其 run() 方法封装了定时要执行的任务,Timer 类负责调度这些任务的执行。

(1)命令模式结构

  • 命令接口:TimerTask 是具体命令类,封装了任务逻辑。
  • 调用者:Timer,负责在指定时间触发命令。

(2)代码示例

TimerTask 的 run() 方法是封装的任务逻辑,Timer 是负责触发任务执行的调用者。

import java.util.Timer;
import java.util.TimerTask;public class TimerCommandExample {public static void main(String[] args) {// 创建一个定时器Timer timer = new Timer();// 创建一个具体命令(TimerTask)TimerTask task = new TimerTask() {@Overridepublic void run() {System.out.println("执行定时任务");}};// 调用者:Timer,调度任务timer.schedule(task, 1000); // 1秒后执行任务}
}

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com