一、概念
1、定义:将请求封装成对象,以便使用不同的请求。(即把不同的请求封装成不同的对象,对于接收者来说它能够识别,然后执行不同的行为)命令模式解决了程序中对象的职责以及它们之间的通信方式(使得发送者和接收者完全解耦,不需要清楚对方的细节)
2、分类:行为型
3、适用场景
- 请求调用者和请求接收者需要解耦,使得调用者和接收者不直接交互
- 需要抽象出等待执行的行为
4、优点:
- 降低耦合
- 容易扩展新的命令或一组命令
5、缺点:
- 命令的无限扩展会增加类的数量,提高系统实现的复杂度。针对每个命令都要开发一个具体的类,对系统来说需要大量的具体命令类,提高了系统的复杂度
6、UML
- Command:命令
- Receiver:命令接收者,也就是命令真正的执行者
- Invoker:通过它来调用命令
- Client:可以设置命令与命令的接收者
二、Coding
//Conmand:写一个命令接口,所有的命令都要实现它
public interface Command {
//执行命令
void execute();
}
//应用场景:课程视频,需要开放或关闭课程的视频
//Receiver:课程视频,接收到开关命令来执行
public class CourseVideo {
private String name;
public CourseVideo(String name) {
this.name = name;
}
//命令1,开放视频,针对命令1创建具体命令类OpenCourseVideoCommand
public void open() {
System.out.println(this.name+"视频开放");
}
//命令2,关闭视频,针对命令2创建具体命令类CloseCourseVideoCommand
public void close() {
System.out.println(this.name+"视频关闭");
}
}
//ConcreteComnand_1:open 创建具体类OpenCourseVideoCommand类
public class OpenCourseVideoCommand implements Command{
//构造器要传入该命令的控制对象
private CourseVideo courseVideo;
public OpenCourseVideoCommand(CourseVideo courseVideo) {
this.courseVideo = courseVideo;
}
@Override
public void execute() {
courseVideo.open();
}
}
//ConcreteComnand_2:close CloseCourseVideoCommand类
public class CloseCourseVideoCommand implements Command {
private CourseVideo courseVideo;
public CloseCourseVideoCommand(CourseVideo courseVideo) {
this.courseVideo = courseVideo;
}
@Override
public void execute() {
courseVideo.close();
}
}
//Invoker:员工类,执行命令的人
public class Staff {
//这个集合中放了很多命令,扩展命令时直接遍历,list还能保证顺序
private List<Command> commandList = new ArrayList<>();
public void addCommand(Command command) {
commandList.add(command);
}
public void executeCommands() {
for (Command command : commandList) {
command.execute();
}
//执行完命令清空
commandList.clear();
}
}
//Client:Test
public class Test {
public static void main(String[] args) {
CourseVideo courseVideo = new CourseVideo("高级软件设计");
//要传入命令控制的对象
OpenCourseVideoCommand openCourseVideoCommand = new OpenCourseVideoCommand(courseVideo);
CloseCourseVideoCommand closeCourseVideoCommand = new CloseCourseVideoCommand(courseVideo);
//添加并执行命令
Staff staff = new Staff();
staff.addCommand(openCourseVideoCommand);
staff.addCommand(closeCourseVideoCommand);
staff.executeCommands();
}
}
三、宏命令
命令模式中的宏命令(mecro command)是多个命令组合在一起的命令,又称为组合命令,它是命令模式和组合模式的产物。宏命令是一个具体命令,包含了对其他对象的引用,在调用宏命令的execute()时,它会调用其成员的execute(),一个宏命令的成员对象可以是简单命令,也可以是宏命令。
模拟开机过程:BIOS -> 主引导记录-> 硬盘启动 -> 操作系统
四个命令:BIOSStartCommand、MBRStartCommand、HDDStartCommand、OSStartCommand;
//命令接口
public interface Command {
void execute();
}
//宏命令接口
public interface MecroCommand extends Command {
//宏命令的增删命令方法
void addCommand(Command command);
void removeCommand(Command command);
}
/**
* 具体宏命令实现
*/
public class ComputerMecroCommand implements MecroCommand {
private ArrayList<Command> commands;
public ComputerMecroCommand() {
commands = new ArrayList<>();
}
@Override
public void addCommand(Command command) {
commands.add(command);
}
@Override
public void removeCommand(Command command) {
commands.remove(command);
}
@Override
public void execute() {
for (Command command : commands) {
command.execute();
}
}
}
//命令接收者Receiver
public class Computer {
public void startBIOS() {
System.out.println("BIOS启动...");
}
public void startMBR(){
System.out.println("MBR加载...");
}
public void startHDD(){
System.out.println("HDD加载...");
}
public void startOS(){
System.out.println("系统启动...");
}
}
//具体命令1
public class BIOSStartCommand implements Command {
private Computer computer;
public BIOSStartCommand(Computer computer) {
this.computer = computer;
}
@Override
public void execute() {
computer.startBIOS();
}
}
//具体命令2
public class MBRStartCommand implements Command {
private Computer computer;
public MBRStartCommand(Computer computer) {
this.computer = computer;
}
@Override
public void execute() {
computer.startMBR();
}
}
//具体命令3
public class HDDStartCommand implements Command {
private Computer computer;
public HDDStartCommand(Computer computer) {
this.computer = computer;
}
@Override
public void execute() {
computer.startHDD();
}
}
//具体命令4
public class OSStartCommand implements Command {
private Computer computer;
public OSStartCommand(Computer computer) {
this.computer = computer;
}
@Override
public void execute() {
computer.startOS();
}
}
//测试类
public class Test {
public static void main(String[] args) {
//创建接收者
Computer computer = new Computer();
//创建命令对象,设定它的接收者
Command bios_command = new BIOSStartCommand(computer);
Command mbr_command = new MBRStartCommand(computer);
Command hdd_command = new HDDStartCommand(computer);
Command os_command = new OSStartCommand(computer);
//具体的宏命令
MecroCommand invoker = new ComputerMecroCommand();
invoker.addCommand(bios_command);
invoker.addCommand(mbr_command);
invoker.addCommand(hdd_command);
invoker.addCommand(os_command);
invoker.execute();
}
}
BIOS启动...
MBR加载...
HDD加载...
系统启动...