1. 命令模式概述
1.命令模式(Command Pattern):在软件设计中,我们需要向部分对象发送请求,但并不知道请求的接收者是谁,也不知道被请求的操作是哪个,我们在程序运行时指定了具体的请求接收者,此时,可以使用命令模式来进行设计。
2.独特的模式植入请求发送者与请求接收者之间的相互连接,使对象的联系更加灵活,实现解耦合。
3.在一个单独的模式中,对象表达一个请求封装为一个也支持可撤销的操作。
4.通俗易懂的理解:将军发布命令,将军角色去执行。有几个角色:将军(命令发布者)、士兵(命令的具体执行行者)、命令(连接将军和士兵)。Invoker 是调用者(将军) , Receiver 是被调用者(部分) , MyCommand 是命令, 实现了命令接口,持有接收对象。
智能生活项目
通过遥控器控制不同家电,因为每个家电的厂家不同,APP不同,所以可以提高命令模式实现解耦。
2. 命令模式实现
LightReceiver
package com.zrj.design.command;
/**
* 电灯命名执行者
*
* @author zrj
* @date 2021/11/6
* @since V1.0
**/
public class LightReceiver {
public void on() {
System.out.println( "电灯打开了" );
}
public void off() {
System.out.println( "电灯关闭了" );
}
}
Command
package com.zrj.design.command;
/**
* 命令接口
*
* @author zrj
* @date 2021/11/6
* @since V1.0
**/
public interface Command {
//执行动作
void execute();
//撤销动作
void undo();
}
LightOffCommand
package com.zrj.design.command;
/**
* 电灯关闭命令类
*
* @author zrj
* @date 2021/11/6
* @since V1.0
**/
public class LightOffCommand implements Command {
//聚合LightReceiver
LightReceiver lightReceiver;
//构造器
public LightOffCommand(LightReceiver lightReceiver) {
this.lightReceiver = lightReceiver;
}
@Override
public void execute() {
//调用接收者的方法
lightReceiver.off();
}
@Override
public void undo() {
//调用接收者的方法
lightReceiver.on();
}
}
LightOnCommand
package com.zrj.design.command;
/**
* 电灯打开关闭命令
*
* @author zrj
* @date 2021/11/6
* @since V1.0
**/
public class LightOnCommand implements Command {
//聚合LightReceiver
LightReceiver lightReceiver;
//构造器
public LightOnCommand(LightReceiver lightReceiver) {
this.lightReceiver = lightReceiver;
}
@Override
public void execute() {
//调用接收者的方法
lightReceiver.on();
}
@Override
public void undo() {
//调用接收者的方法
lightReceiver.off();
}
}
NoCommand
package com.zrj.design.command;
/**
* 空命令类
* 没有任何命令,即空执行:用于初始化每个按钮,当调用空命令时,对象什么都不做
* 其实,这也是一种设计模式,可以省掉对空判断的处理
*
* @author zrj
* @date 2021/11/6
* @since V1.0
**/
public class NoCommand implements Command {
@Override
public void execute() {
System.out.println("空命令");
}
@Override
public void undo() {
System.out.println("空命令");
}
}
RemoteController
package com.zrj.design.command;
/**
* 遥控器类
*
* @author zrj
* @date 2021/11/6
* @since V1.0
**/
public class RemoteController {
//开关按钮的命令数组
Command[] onCommands;
Command[] offCommands;
//执行撤销按钮操作
Command undoCommand;
//构造器,完成对按钮的初始化
public RemoteController() {
onCommands = new Command[5];
offCommands = new Command[5];
for (int i = 0; i < 5; i++) {
onCommands[i] = new NoCommand();
offCommands[i] = new NoCommand();
}
}
//给我们的按钮设置你需要的命令即可
public void setCommand(int no, Command onCommand, Command offCommand) {
onCommands[no] = onCommand;
offCommands[no] = offCommand;
}
//按下开按钮
public void onButtonWasPushed(int no) {
onCommands[no].execute();
//记录这次操作,用于撤销
undoCommand = onCommands[no];
}
public void offButtonWasPushed(int no) {
offCommands[no].execute();
undoCommand = offCommands[no];
}
//撤销
public void undoButtonWasPushed() {
undoCommand.undo();
}
}
CommandClient
package com.zrj.design.command;
/**
* @author zrj
* @date 2021/11/6
* @since V1.0
**/
public class CommandClient {
public static void main(String[] args) {
//使用命令设计模式,完成通过遥控器,对电灯的控制
//创建电灯的对象(接收者)
LightReceiver lightReceiver = new LightReceiver();
//创建电灯相关的开关命令
LightOnCommand lightOnCommand = new LightOnCommand( lightReceiver );
LightOffCommand lightOffCommand = new LightOffCommand( lightReceiver );
//创建遥控器
RemoteController remoteController = new RemoteController();
//给遥控器设置相关的命令 比如 no=0是电灯的开关操作
remoteController.setCommand( 0, lightOnCommand, lightOffCommand );
System.out.println( "---按下电灯开的按钮---" );
remoteController.onButtonWasPushed( 0 );
System.out.println( "---按下电灯关的按钮---" );
remoteController.offButtonWasPushed( 0 );
System.out.println( "---撤销---" );
remoteController.undoButtonWasPushed();
}
}