Command设计模式

1、概要

该模式把一个请求或者操作封装到一个对象中。把发出命令和执行命令分隔开,委派给不同的对象。因为把各种命令封装成了一个一个的对象,所以可以灵活地对命令进行管理。比如:Undo和Redo。

 

2、什么时候需要使用Command设计模式?

  • 需要实现Undo/Redo功能的时候
  • 有的系统需要在数据更新的同时,把更新日志记录下来,如果系统崩溃,可以根据日志信息里记录下来的命令,重新执行系统崩溃前做的操作,从而恢复系统崩溃前做的数据更新

3、命令模式涉及到的角色

 

客户(Client)角色:

        ・命令的发出者,把接收者指定给具体命令对象

    ・把具体命令对象指定给Invoker,并通过调用Invoker的接口方法来发出执行命令的请求

请求者(Invoker)角色:

        ・相当于连接客户对象和命令对象之间的桥梁,可以想象成控制电视机的遥控器

        ・负责调用命令对象提供的方法,执行请求

抽象命令(Command)角色:

        ・所有具体命令类的父类,为了使用运行时多态

具体命令(ConcreteCommand)角色:

        ・封装具体命令的类

        ・调用Receiver的方法,执行请求

接收者(Receiver)角色:

        ・请求和操作的实际执行者

 

这五种角色的关系可以理解为上下级关系:

  • 客户是最高级,它负责协调其他角色之间的关系,并发布命令,比如:把接收者委派给具体命令来管理,把具体命令委派给Invoker去管理
  • 请求者管理具体命令,向具体命令发布命令
  • 具体命令管理接收者,并向接收者下达命令
  • 接收者是最低级,它只能接收命令,并执行具体的操作

示例代码:

 

相当于人通过遥控器控制电视机的打开和关闭,并实现了简单的Undo和Redo功能。

每次执行完一个命令的时候,把命令句柄保存起来,Redo的时候,直接调用doCmd.execute方法即可;

Undo的时候,直接调用doCmd的undo方法即可。Redo相对简单一些,因为只要重做前一次的操作即可。

 

public class CommandTest{
 public static void main(String[] args){
  Tvset tv = new Tvset();
  TurnonCommand cmdOn = new TurnonCommand(tv);
  TurnoffCommand cmdOff = new TurnoffCommand(tv);
  RemoteController rc = new RemoteController();
  rc.setCommand(cmdOn,cmdOff);
  rc.turnOn();
  rc.turnOff();
  rc.redo();
  rc.undo();
 } 

}

 

class RemoteController{
 private Command cmdOn;
 private Command cmdOff;
 private Command doCmd;

 public void setCommand(Command cmdOn,Command cmdOff){
  this.cmdOn = cmdOn;
  this.cmdOff = cmdOff;
 }
 
 public void turnOn(){
  cmdOn.execute();
  doCmd=cmdOn;
 }

 public void turnOff(){
  cmdOff.execute();
  doCmd=cmdOff;
 }
 public void redo(){
  System.out.println("Redo start...");
  doCmd.execute();
  System.out.println("Redo end.");
 }
 public void undo(){
  System.out.println("Undo start...");
  doCmd.undo();
  System.out.println("Undo end.");
 }
}

 

 

abstract class Command{
 protected abstract void execute();
 protected abstract void undo();
}

 

 

class TurnonCommand extends Command{
 private Tvset tv;
 public TurnonCommand(Tvset tv){
  this.tv=tv;
 }
 public void execute(){
  tv.turnOn();
 }
 public void undo(){
  tv.turnOff();
 }
}

 

 

class TurnoffCommand extends Command{
 private Tvset tv;
 public TurnoffCommand(Tvset tv){
  this.tv=tv;
 }
 public void execute(){
  tv.turnOff();
 }
 public void undo(){
  tv.turnOn();
 }
}

 

 

class Tvset{
 public void turnOn(){
  System.out.println("Tvset turn on!");
 }

 public void turnOff(){
  System.out.println("Tvset turn off!");
 }
}

 

执行结果:

C:\javastudy>java CommandTest
Tvset turn on!
Tvset turn off!
Redo start...
Tvset turn off!
Redo end.
Undo start...
Tvset turn on!
Undo end.

C:\javastudy>

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值