命令模式是对命令的封装,每个命令都是一个操做:请求方发出请求要求执行一个操做;接收方收到请求,并执行操做。命令模式解耦了请求方shell
和接收方,请求方只需请求执行命令,不用关心命令怎么被接收、怎样操做以及是否被执行等。命令模式属于行为型设计模式。设计模式
在软件系统中,行为请求者与行为实现者一般是一种紧耦合关系,由于这样的实现简单明了。但紧耦合关系缺少扩展性,在某些场合中,须要对行为架构
进行记录、撤销或者重作等处理时,只能修改源码。而命令模式经过在请求与实现之间引入一个抽象命令接口。解耦了请求与实现,而且中间件是抽象的,测试
它由不一样的子类实现,所以具备扩展性。因此,命令模式的本质是解耦命令请求与处理。this
从上图能够看出,命令模式主要包含4个角色。spa
从命令模式的UML类图中,能够很清晰地看出,ICommand的出现就是做为Receiver和Invoker的中间件,解耦了彼此。命令行
假如咱们开发一个播放器,播放器播放功能、拖动进度条功能、中止播放功能、暂停功能,咱们在操做播发器的时候并不知道之间调用播放器设计
哪一个功能,而是经过一个控制传达去传递指令给播放器内核,具体传达什么指令,会被封装成一个个按钮。那么每一个按钮就至关于一条命令的封装。日志
用控制条实现了用户发送指令与播放器内核接收指令的解耦。下面来看代码,首先建立播放器内核类:code
public class GPlayer { public void play() { System.out.println("正常播放"); } public void speed() { System.out.println("拖动进度条"); } public void stop() { System.out.println("中止播放"); } public void pause() { System.out.println("暂停播放"); } }
建立命令接口:
public interface IAction { void execute(); }
建立播放指令类:
public class PlayAction implements IAction { private GPlayer gplayer; public PlayAction(GPlayer gplayer) { this.gplayer = gplayer; } public void execute() { gplayer.play(); } }
建立暂停指令类:
public class PauseAction implements IAction { private GPlayer gplayer; public PauseAction(GPlayer gplayer) { this.gplayer = gplayer; } public void execute() { gplayer.pause(); } }
建立拖动进度条类:
public class SpeedAction implements IAction { private GPlayer gplayer; public SpeedAction(GPlayer gplayer) { this.gplayer = gplayer; } public void execute() { gplayer.speed(); } }
建立中止播放指令:
public class StopAction implements IAction { private GPlayer gplayer; public StopAction(GPlayer gplayer) { this.gplayer = gplayer; } public void execute() { gplayer.stop(); } }
建立控制条controller类:
public class Controller { private List<IAction> actions = new ArrayList<IAction>(); public void addAction(IAction action) { actions.add(action); } public void execute(IAction action) { action.execute(); } public void executes() { for (IAction action : actions) { action.execute(); } actions.clear(); } }
从上面代码来看,控制条能够执行单条命令,也能够批量执行多条命令。下面看客户端的测试代码:
public class Test { public static void main(String[] args) { GPlayer player = new GPlayer(); Controller controller = new Controller(); controller.execute(new PlayAction(player)); controller.addAction(new PauseAction(player)); controller.addAction(new PlayAction(player)); controller.addAction(new StopAction(player)); controller.addAction(new SpeedAction(player)); controller.executes(); } }
因为控制条已经与播放器内核解耦了,之后若是想扩展新命令,只须要增长命令便可,控制条的结构无须改动。