Command:命令
ConcreteCommand:具体的命令
Invoker:调用者
Receiver:接受者
标准UML类图
角色
Command 抽象命令 执行命令 撤销命令
ConcreteCommand LightOnCommand 开灯 LightOffCommand 关灯
NonCommand
空命令
Invoker 调用者 遥控器聚合所有命令 Command[] ons Command[] offs Command undo
Receiver 接受者 电灯、空调、电视
案例
需求:万能遥控器的制作
案例UML类图
出现前
package com.javaxl.design.command.before;
/**
* @author 小李飞刀
* @site www.javaxl.com
* @company
* @create 2020-02-24 18:14
*
* 被操作的对象
*/
public class Light {
public void on(){
System.out.println("电灯打开...");
}
public void off(){
System.out.println("电灯关闭...");
}
}
class AirConditioner {
public void on(){
System.out.println("空调打开...");
}
public void off(){
System.out.println("空调关闭...");
}
}
class Television {
public void on(){
System.out.println("电视打开...");
}
public void off(){
System.out.println("电视关闭...");
}
}
public class Invoker {
private Light light = new Light();
private AirConditioner airConditioner = new AirConditioner();
private Television television = new Television();
public void lightOn(){
light.on();
}
public void lightOff(){
light.off();
}
public void airOn(){
airConditioner.on();
}
public void airOff(){
airConditioner.off();
}
public void tvOn(){
television.on();
}
public void tvOff(){
television.off();
}
}
public class Client {
public static void main(String[] args) {
Invoker invoker = new Invoker();
invoker.lightOn();
invoker.lightOff();
System.out.println("=============");
invoker.airOn();
invoker.airOff();
System.out.println("=============");
invoker.tvOn();
invoker.tvOff();
}
}
出现后
package com.javaxl.design.command.after;
/**
* @author 小李飞刀
* @site www.javaxl.com
* @company
* @create 2020-02-24 18:14
*
* 被操作的对象
*/
public class Light {
public void on(){
System.out.println("电灯打开...");
}
public void off(){
System.out.println("电灯关闭...");
}
}
class AirConditioner {
public void on(){
System.out.println("空调打开...");
}
public void off(){
System.out.println("空调关闭...");
}
}
class Television {
public void on(){
System.out.println("电视打开...");
}
public void off(){
System.out.println("电视关闭...");
}
}
package com.javaxl.design.command.after;
/**
* @author 小李飞刀
* @site www.javaxl.com
* @company
* @create 2020-02-24 18:25
*/
interface Command {
void execute();
void undo();
}
//空命令
class NonCommand implements Command {
@Override
public void execute() {
}
@Override
public void undo() {
}
}
class LightOnCommand implements Command {
private Light light = new Light();
@Override
public void execute() {
light.on();
}
@Override
public void undo() {
light.off();
}
}
class LightOffCommand implements Command {
private Light light = new Light();
@Override
public void execute() {
light.off();
}
@Override
public void undo() {
light.on();
}
}
class TvOnCommand implements Command {
private Television tv = new Television();
@Override
public void execute() {
tv.on();
}
@Override
public void undo() {
tv.off();
}
}
class TvOffCommand implements Command {
private Television tv = new Television();
@Override
public void execute() {
tv.off();
}
@Override
public void undo() {
tv.on();
}
}
public class Invoker {
Command[] ons;
Command[] offs;
// 记录上一个命令
Command command;
public Invoker(int n) {
ons = new Command[n];
offs = new Command[n];
command = new NonCommand();
for (int i = 0; i < n; i++) {
setCommand(i,new NonCommand(),new NonCommand());
}
}
public void setCommand(int no, Command on, Command off){
ons[no]=on;
offs[no]=off;
}
public Command getOnCommand(int no){
return ons[no];
}
public Command getOffCommand(int no){
return offs[no];
}
// 执行命令
public void invoke(Command command){
// 执行当前命令
command.execute();
// 保存当前执行命令
this.command = command;
}
// 撤销命令(上个操作的反操作)
public void undo(){
// 这里就能体现定义一个空命令的好处了,如果第一次按撤销命令,那么应该什么都不做;
// 如果没有定义空命令的话,此时就需要判断空处理了
command.undo();
}
}
public class Client {
public static void main(String[] args) {
Invoker invoker = new Invoker(2);
invoker.setCommand(0, new LightOnCommand(), new LightOffCommand());
invoker.setCommand(1, new TvOnCommand(), new TvOffCommand());
System.out.println("电灯打开关闭操作===========");
invoker.invoke(invoker.getOnCommand(0));
invoker.invoke(invoker.getOffCommand(0));
// invoker.undo();
System.out.println("电视打开关闭操作===========");
invoker.invoke(invoker.getOnCommand(1));
invoker.undo();
}
}
注意事项和细节 将发起请求的对象与执行请求的对象解耦 容易实现对请求的撤销和重做 空命令也是一种设计模式,它为我们省去了判空的操作
命令模式不足: 可能导致某些系统有过多的具体命令类,增加了系统的复杂度
与外观模式相似:都是将多个功能聚合在一起 外观模式更多适用于维护;命令模式更多应用于设计;
应用 Spring框架中的JdbcTemplate类 容易设计一个命令队列。只要把命令对象放到列队,就可以多线程的执行命令 界面的一个按钮都是一条命令、模拟 CMD(DOS 命令)订单的撤销/恢复、触发- 反馈机制
over......
备案号:湘ICP备19000029号
Copyright © 2018-2019 javaxl晓码阁 版权所有