将一个请求封装为对象,从而使你可以用不同的请求对客户进行参数化;对请求排队或记录请求日志,以及支持可撤销的操作
invoker中包含一系列命令,客户端通过调用invoker来使得多条命令封装在一起被执行,方便回滚以及事务处理
命令模式的优点
首先,命令模式的封装性很好:每个命令都被封装起来,对于客户端来说,需要什么功能就去调用相应的命令,而无需知道命令具体是怎么执行的。比如有一组文件操作的命令:新建文件、复制文件、删除文件。如果把这三个操作都封装成一个命令类,客户端只需要知道有这三个命令类即可,至于命令类中封装好的逻辑,客户端则无需知道。
其次,命令模式的扩展性很好,在命令模式中,在接收者类中一般会对操作进行最基本的封装,命令类则通过对这些基本的操作进行二次封装,当增加新命令的时候,对命令类的编写一般不是从零开始的,有大量的接收者类可供调用,也有大量的命令类可供调用,代码的复用性很好。比如,文件的操作中,我们需要增加一个剪切文件的命令,则只需要把复制文件和删除文件这两个命令组合一下就行了,非常方便。
命令模式的缺点
命令如果很多,开发起来就要头疼了。特别是很多简单的命令,实现起来就几行代码的事,而使用命令模式的话,不用管命令多简单,都需要写一个命令类来封装。
命令模式的适用场景
对于大多数请求-响应模式的功能,比较适合使用命令模式,正如命令模式定义说的那样,命令模式对实现记录日志、撤销操作等功能比较方便。
代码
Main
public class Main {
public static void main(String[] args) {
TV tv=new TV();
CommandOn on=new CommandOn(tv);
CommandOff off=new CommandOff(tv);
CommandChange change=new CommandChange(tv, 3);
Control c=new Control(on, off, change);
c.trunOn();
c.turnOff();
c.changeChanel();
}
}
interface:Command
public interface Command {
public void execute();
}
imp:TV
public class TV {
public int chanel=0;
public void trunOn(){
System.out.println("trun on");
}
public void trunOff(){
System.out.println("trun off");
}
public void changeChanel(int chanel){
this.chanel=chanel;
System.out.println("the chanel is "+this.chanel);
}
}
imp:CommandOn
public class CommandOn implements Command {
private TV tv=null;
public CommandOn(TV tv){
this.tv=tv;
}
@Override
public void execute() {
tv.trunOn();
}
}
imp:CommandOff
public class CommandOff implements Command {
private TV tv=null;
public CommandOff(TV tv){
this.tv=tv;
}
@Override
public void execute() {
this.tv.trunOff();
}
}
imp:CommandChange
public class CommandChange implements Command {
private TV tv=null;
private int chanel;
public CommandChange(TV tv,int chanel){
this.tv=tv;
this.chanel=chanel;
}
@Override
public void execute() {
this.tv.changeChanel(this.chanel);
}
}
imp:Control
public class Control {
private Command commandOn,commandOff,changeChanel;
public Control(Command on,Command off,Command change){
this.commandOn=on;
this.commandOff=off;
this.changeChanel=change;
}
public void trunOn(){
this.commandOn.execute();
}
public void turnOff(){
this.commandOff.execute();
}
public void changeChanel(){
this.changeChanel.execute();
}
}
网友评论