一、命令模式定义

1.命令模式是对命令的封装,每一个命令都是一个操作:请求的一方发出请求要求执行一个操作;接收的一方收到请求,并执行操作。命令模式解耦了请求方和接收方,请求方只需请求执行命令,不用关心命令是怎么被接收,怎样被操作以及是否被执行等。属于行为型模式

2.命令模式的本质是解耦命令请求与处理

3.命令模式的应用场景:

  A.现实语义中具备”命令“的操作(如命令菜单、shell命令)

  B.请求调用者和请求的接收者需要解耦,使得调用者和接收者不直接交互

  C.需要抽象出等待执行的行为,比如撤销(Undo)操作和恢复(Redo)等操作

  D.需要支持命令宏(即命令组合操作)

二、命令模式示例

1.命令模式主要包含四种角色:

  A.接收者角色(Receiver):该类负责具体实施或执行一个请求

  B.命令角色(Command):定义需要执行的所有命令行为

  C.具体命令角色(ConcreteCommand):该类内部维护一个接收者,在其execute()方法中调用Receiver的相关方法

  D.请求者角色(Invoker):接收客户端的命令,并执行命令

2.代码示例

  1 public class GPPlayer {
  2     public void play(){
  3         System.out.println("正常播放");
  4     }
  5 
  6     public void speed(){
  7         System.out.println("拖动进度条");
  8     }
  9 
 10     public void stop(){
 11         System.out.println("停止播放");
 12     }
 13 
 14     public void pause(){
 15         System.out.println("暂停播放");
 16     }
 17 }
 18 
 19 public interface IAction {
 20     void execute();
 21 }
 22 
 23 public class PlayAction implements IAction {
 24 
 25     private GPPlayer gpPlayer;
 26 
 27     public PlayAction(GPPlayer gpPlayer){
 28         this.gpPlayer = gpPlayer;
 29     }
 30 
 31     @Override
 32     public void execute() {
 33         gpPlayer.play();
 34     }
 35 }
 36 
 37 public class PauseAction implements IAction {
 38 
 39     private GPPlayer gpPlayer;
 40 
 41     public PauseAction(GPPlayer gpPlayer){
 42         this.gpPlayer = gpPlayer;
 43     }
 44 
 45     @Override
 46     public void execute() {
 47         gpPlayer.pause();
 48     }
 49 }
 50 
 51 public class SpeedAction implements IAction {
 52 
 53     private GPPlayer gpPlayer;
 54 
 55     public SpeedAction(GPPlayer gpPlayer){
 56         this.gpPlayer = gpPlayer;
 57     }
 58 
 59     @Override
 60     public void execute() {
 61         gpPlayer.speed();
 62     }
 63 }
 64 
 65 public class StopAction implements IAction {
 66 
 67     private GPPlayer gpPlayer;
 68 
 69     public StopAction(GPPlayer gpPlayer){
 70         this.gpPlayer = gpPlayer;
 71     }
 72 
 73     @Override
 74     public void execute() {
 75         gpPlayer.stop();
 76     }
 77 }
 78 
 79 public class Controller {
 80 
 81     private List<IAction> actions = new ArrayList<IAction>();
 82 
 83     public void addAction(IAction action){
 84         actions.add(action);
 85     }
 86 
 87     public void execute(IAction action){
 88         action.execute();
 89     }
 90 
 91     public void executes(){
 92         for(IAction action : actions){
 93             action.execute();
 94         }
 95         actions.clear();
 96     }
 97 }
 98 
 99 public class CommandTest {
100     public static void main(String[] args) {
101         GPPlayer player = new GPPlayer();
102         Controller controller = new Controller();
103         controller.execute(new PlayAction(player));
104 
105         controller.addAction(new PauseAction(player));
106         controller.addAction(new PlayAction(player));
107         controller.addAction(new StopAction(player));
108         controller.addAction(new SpeedAction(player));
109         controller.executes();
110     }
111 }

3.命令模式的优缺点

  A.优点

    a.通过引入中间件(抽象接口),解耦了命令请求和实现

    b.扩展性良好,可以很容易的增加新命令

    c.支持组合命令,支持命令队列

    d.可以在现有命令的基础上,增加额外功能

  B.缺点

    a.具体命令类可能过多

    b.增加了理解的难度