一、命令模式定义
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.增加了理解的难度