一、命令模式概述
命令模式可以将请求发送者和接收者完全解耦,发送者与接收者之间没有直接引用关系,发送请求的对象只需要知道如何发送请求,而不必知道如何完成请求。
定义:
命令模式:将一个请求封装为一个对象,从而可用不同的请求对客户进行参数化,对请求排队或者记录请求日志,以及支持可撤销的操作。
二、命令模式的结构和实现
2.1 命令模式的结构
命令模式包含以下4个角色:
- Command(抽象命令类):抽象命令类一般是一个抽象类或接口,在其中声明了用于执行请求的execute()等方法,通过这些方法可以调用请求接收者的相关操作。
- ConcreteCommand(具体命令类):具体命令类是抽象命令类的子类,实现了在抽象命令类中声明的方法,它对应具体的接收者对象,将接收者对象的动作绑定其中。具体命令类在实现execute()方法时,将调用接收者对象的相关操作(Action)。
- Invoker(调用者):调用者即请求发送者,它通过命令对象来执行请求。
- Receiver(接收者):接收者执行与请求相关的操作,具体实现对请求的业务处理。
2.2 命令模式的实现
//请求调用者
/**
* 菜单项,充当请求调用者
*/
public class MenuItem {
private Command command;
public void setCommand(Command command) {
this.command = command;
}
public void click(){
System.out.println("单击功能键:");
command.execute();
}
}
/**
* 主菜单
*/
public class Menu {
private ArrayList<MenuItem> menuItems = new ArrayList<>();
public void addMenuItem(MenuItem menuItem){
menuItems.add(menuItem);
}
}
//抽象命令类
/**
* 抽象命令类
*/
public abstract class Command {
public abstract void execute();
}
//具体命令类
/**
* 创建命令类,具体命令类
*/
public class CreateCommand extends Command{
private BoardScreen boardScreen;
public CreateCommand(BoardScreen boardScreen){
this.boardScreen = boardScreen;
}
@Override
public void execute() {
boardScreen.create();
}
}
/**
* 编辑命令类,具体命令类
*/
public class EditCommand extends Command{
private BoardScreen boardScreen;
public EditCommand(BoardScreen boardScreen){
this.boardScreen = boardScreen;
}
@Override
public void execute() {
boardScreen.edit();
}
}
/**
* 打开命令类,具体命令类
*/
public class OpenCommand extends Command{
private BoardScreen boardScreen;
public OpenCommand(BoardScreen boardScreen){
this.boardScreen = boardScreen;
}
@Override
public void execute() {
boardScreen.open();
}
}
//请求接收者
/**
* 公告板系统界面类
*/
public class BoardScreen {
public void open(){
System.out.println("公告板界面打开功能");
}
public void create(){
System.out.println("公告板界面创建功能");
}
public void edit(){
System.out.println("公告板界面编辑功能");
}
}
//客户端
public class Client {
public static void main(String[] args) {
/**
* 案例需求描述:
* 开发一个公告板系统,系统提供一个主菜单Menu,在主菜单中包含了一些菜单项MenuItem,
* 可以通过Menu类的addMenuItem()方法增加菜单项。
* 菜单项的主要方法是click(),每一个菜单项包含一个抽象命令类,具体命令类包括openCommand(打开命令),
* createCommand(新建命令),editCommand(编辑命令)等,命令类有一个execute()方法,
* 用于调用公告板系统界面类(BoardScreen)的open(),create(),edit()等方法。
* 请使用命令模式设计该系统。
*/
BoardScreen boardScreen = new BoardScreen();
Command create, edit, open;
create = new CreateCommand(boardScreen);
edit = new EditCommand(boardScreen);
open = new OpenCommand(boardScreen);
MenuItem menuItem = new MenuItem();
menuItem.setCommand(create);
menuItem.click();
menuItem.setCommand(edit);
menuItem.click();
menuItem.setCommand(open);
menuItem.click();
Menu menu = new Menu();
menu.addMenuItem(menuItem);
}
}
三、命令模式的优缺点和适用环境
3.1 命令模式的优点
3.2 命令模式的缺点
- 使用命令模式可能会导致某些系统有过多的具体命令类
3.3 命令模式的适用环境
- 系统需要将请求调用者和请求接收者解耦,使得调用者和接收者不直接交互
- 系统需要在不同的时间指定请求,将请求排队和执行请求
- 系统需要支持命令的撤销操作和恢复操作
- 系统需要将一组操作组合在一起形成宏命令(组合命令)
【参考文献】:
本文是根据刘伟的《Java设计模式》一书的学习笔记,仅供学习用途,勿做其他用途,请尊重知识产权。
【本文代码仓库】:https://gitee.com/xiongbomy/java-design-pattern.git
原文地址:https://www.jb51.cc/wenti/3280206.html
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。