【设计模式与体系结构】行为型模式-命令模式
简介
命令模式(Command Pattern)是一种行为型模式,它将请求封装成一个对象,从而你可以用不同的请求将客户参数化,对请求排队或记录请求日志,以及支持可撤销操作。
命令模式的角色
- 抽象命令(Command)接口:定义抽象命令接口,通常包含一个execute()方法
- 具体命令(Concrete Command)类:实现抽象命令接口,负责调用接收者的相应操作,并将接收者对象绑定到该命令中
- 接收者(Receiver)类:知道如何执行与请求相关的操作,实现具体业务逻辑
- 调用者(Invoker)类:负责调用命令者类执行相关请求,不直接与接收者交互
- 客户端:创建命令对象并设置其接收者对象,然后将命令传给调用者对象
命令模式的优点
- 请求与实现的解耦:命令者模式将调用者和接收者进行解耦,使得二者无需直接交互,提高了系统的可维护性和可扩展性
- 支持撤销与重做:可以在命令类中实现撤销方法和重做方法,提高系统的交互性
- 符合开闭原则:只需要新增具体命令类,而无需修改已有的代码逻辑,提高了系统的可维护性和可扩展性
命令模式的缺点
- 系统复杂性增加:每增加一个具体命令,都需要添加一个具体命令类
- 维护难度高:当具体命令的数量较多时,维护会比较困难
命令模式的使用场景
- 菜单系统:在图形界面应用程序中,菜单系统通常会有各种操作:打开文件、保存文件等。可以将每个菜单项封装成一个命令对象,方便管理和执行
- 任务队列:将请求封装成命令对象以后,可以将这些命令对象放入队列中,实现任务的排队和异步执行
- 撤销和重做功能:在文本编辑器、图形处理软件等应用中,经常需要实现撤销和重做操作,命令模式可以很好地支持这一功能。
正文
打开一个图形化界面,或者是网页界面,我们常常会看到有“最大化按钮”、“最小化按钮”以及“关闭界面按钮”等等。这些按钮的逻辑各不相同,但对于界面来说,都仅仅只是一个按钮。由于用户也有个性化设置需求,有些用户喜欢修改这些按钮的顺序,那么如果这些按钮就像一些电器的插头一样,而按钮的位置就像插座一样,只需要插拔一下,就会十分方便。下面我们就以图形化界面的按钮功能作为案例,进行代码分析。
首先,定义一个接收者(Receiver)接口 Receiver.java。接收者仅负责执行具体的业务逻辑,无需持有外部依赖,且一个系统会有多种业务逻辑,因此设计为接口较为合适。
public interface Receiver { void action();//执行具体业务逻辑 }
以“最大化按钮”为案例,定义一个 MaximiseReceiver.java,负责执行“窗口最大化”的功能需求。
public class MaximiseReceiver implements Receiver { @Override public void action() { System.out.println("窗口最大化"); } }
定义一个抽象命令类 Command.java。该类需要注入一个接收者对象,并且要有一个抽象的执行方法(execute()方法),因此设计为一个抽象类较为合适。
public abstract class Command { private Receiver receiver; public Command(Receiver receiver) { this.receiver = receiver; } public Receiver getReceiver() { return receiver; } public void setReceiver(Receiver receiver) { this.receiver = receiver; } abstract void execute(); }
定义一个“最大化按钮”的具体命令类 MaximiseCommand.java
public class MaximiseCommand extends Command { public MaximiseCommand(Receiver receiver) { super(receiver); } @Override public void execute() { getReceiver().action(); } }
定义一个调用者类 Invoker.java。该类需要持有一个具体命令对象,并且可以调用具体命令对象的命令,可以设计为一个普通的类,也可以设计为一个抽象类。
public class Invoker { private Command mCommand; public Invoker(Command command) { this.mCommand = command; } public void setCommand(Command command) { this.mCommand = command; } public void call() { mCommand.execute(); } }
定义一个客户端 Client.java
public class Client { public static void main(String[] args) { Receiver receiver = new MaximiseReceiver(); Command maximiseCommand = new MaximiseCommand(receiver); Invoker invoker = new Invoker(maximiseCommand); invoker.call(); } }
合集:
行为型模式
分类:
设计模式与体系结构 / 设计模式
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 本地部署 DeepSeek:小白也能轻松搞定!
· 如何给本地部署的DeepSeek投喂数据,让他更懂你
· 从 Windows Forms 到微服务的经验教训
· 李飞飞的50美金比肩DeepSeek把CEO忽悠瘸了,倒霉的却是程序员
· 超详细,DeepSeek 接入PyCharm实现AI编程!(支持本地部署DeepSeek及官方Dee