命令模式:适用于命令型操作并命令内容以后不会修改如:文件操作密命令增删改等响应式操作。
其定义:将一个请求封装成一个对象,从而让你使用不同的请求把客户端参数化,对请求排队或者记录请求日志,可以提供命令的撤销和恢复功能。
其缺点是命令如果很多,开发起来就要头疼了。特别是很多简单的命令,实现起来就几行代码的事,而使用命令模式的话,不用管命令多简单,都需要写一个命令类来封装。
-
一般来说,我们会把对请求的响应操作封装到一个方法中,这个封装的方法可以称之为命令,但不是命令模式。到底要不要把这种设计上升到模式的高度就要另行考虑了,
-
因为,如果使用命令模式,就要引入调用者、接收者两个角色,原本放在一处的逻辑分散到了三个类中,设计时,必须考虑这样的代价是否值得。
-
实际适用中虽然适用场景很多,但多数场景不使用该模式,1、代码多、简单代码复杂化。2、一般敏捷开发中,需求会变动,修改内容多,开发周期长,效率低。
例子:下棋
棋手通过命令来操控棋子运动。
命令接口
public interface ICommand {
void execute();
}
命令接口实现类
后退
public class DrawBackCommand implements ICommand {
private Piece piece;
public DrawBackCommand(Piece piece) {
this.piece = piece;
}
@Override
public void execute() {
piece.drawBack();
}
}
前进
public class GoForwardCommand implements ICommand{
private Piece piece;
public GoForwardCommand(Piece piece){
this.piece = piece;
}
@Override
public void execute() {
piece.goForward();
}
}
接收者
棋子
public class Piece {
public void goForward(){
System.out.println("棋子前进");
}
public void drawBack(){
System.out.println("棋子后退");
}
}
调用者
棋手
public class ChessPlayer {
private List list = new ArrayList();
public void play(){
for(int i = 0; i < list.size(); i++){
ICommand command = (ICommand) list.get(i);
command.execute();
}
}
public void addCommand(ICommand command){
list.add(command);
}
}
运行
棋手命令棋子向前
public class Client {
public static void main(String[] args) {
Piece piece = new Piece();
ICommand goForwardCommand = new GoForwardCommand(piece);
ChessPlayer chessPlayer =new ChessPlayer();
chessPlayer.addCommand(goForwardCommand);
//chessPlayer.play();
ICommand drawBackCommand = new DrawBackCommand(piece);
chessPlayer.addCommand(drawBackCommand);
chessPlayer.play();
}
}