命令模式
命令模式很好理解,举个例子,司令员下令让士兵去干件事情,从整个事情的角度来考虑,司令员的作用是,发出口令,口令经过传递,传到了士兵耳朵里,士兵去执行。这个过程好在,三者相互解耦,任何一方都不用去依赖其他人,只需要做好自己的事儿就行,司令员要的是结果,不会去关注到底士兵是怎么实现的。我们看看关系图:
Invoker是调用者(司令员),Receiver是被调用者(士兵),MyCommand是命令,实现了Command接口,持有接收对象,看实现代码:
实例代码一:
/** *命令接口 */ public interface Command { public void exe(); } ************************************************************************* public class Receiver { public void action(){ System.out.println("command received!"); } } ************************************************************************* public class MyCommand implements Command { private Receiver receiver; public MyCommand(Receiver receiver) { this.receiver = receiver; } public Receiver getReceiver() { return receiver; } public void setReceiver(Receiver receiver) { this.receiver = receiver; } @Override public void exe() { receiver.action(); } } ************************************************************************* public class Invoker { private Command command; public Invoker(Command command) { this.command = command; } public Command getCommand() { return command; } public void setCommand(Command command) { this.command = command; } public void action() { command.exe(); } } ************************************************************************* /** * innvoker 中调用cmmand ,command中持有recover的引用,这样客户端只需要跟invoker交互就可以,具体的执行命令下发下去由receiver执行 * * 命令模式的目的就是达到命令的发出者和执行者之间解耦,实现请求和执行分开, */ public class MainClass { public static void main(String[] args) { Receiver receiver = new Receiver(); Command command = new MyCommand(receiver); Invoker invoker = new Invoker(command); invoker.action(); } } ************************************************************************* 测试结果: command received! *************************************************************************
实例代码二:
public interface Command { void execute(); } ******************************************************* /* The Invoker class */ public class Switch { private List<Command> history = new ArrayList<>(); public Switch() { } public void storeAndExecute(Command cmd) { this.history.add(cmd); // optional cmd.execute(); } } ******************************************************* /* The Receiver class */ public class Light { public Light() { } public void turnOn() { System.out.println("The light is on"); } public void turnOff() { System.out.println("The light is off"); } } ******************************************************* /* The Command for turning on the light - ConcreteCommand #1 */ public class FlipUpCommand implements Command { private Light theLight; public FlipUpCommand(Light light) { this.theLight = light; } public void execute(){ theLight.turnOn(); } } ******************************************************* /* The Command for turning off the light - ConcreteCommand #2 */ public class FlipDownCommand implements Command { private Light theLight; public FlipDownCommand(Light light) { this.theLight = light; } public void execute() { theLight.turnOff(); } } ******************************************************* /* The test class or client */ public class PressSwitch { public static void main(String[] args){ Light lamp = new Light(); Command switchUp = new FlipUpCommand(lamp); Command switchDown = new FlipDownCommand(lamp); Switch mySwitch = new Switch(); try { if ("ON".equalsIgnoreCase(args[0])) { mySwitch.storeAndExecute(switchUp); } else if ("OFF".equalsIgnoreCase(args[0])) { mySwitch.storeAndExecute(switchDown); } else { System.out.println("Argument \"ON\" or \"OFF\" is required."); } } catch (Exception e) { System.out.println("Arguments required."); } } }
实例代码三:
********************************************************************* /** * 一个对象调用灵位一个对象,一般情况下的调用过程是:创建目标对象实例,设置调用参数,调用目标对象方法 * * 但是有些情况下有必要使用一个专门的类对这种调用过程加以封装,我们把这种称为Command类 * * 整个过程调用比较繁琐,或者存在多处调用,这时候使用Command类对该调用加以封装,便于功能再利用 * * 调用前后需要对调用参数进行某些处理 * * 调用前后需要进行某些额外的处理,比如日志,缓存,记录历史等操作。 */ public interface Command { public void sail(); } ********************************************************************* /** * 商贩卖水果 */ public class Peddle { public void sailAppl() { System.out.println("卖苹果"); } public void sailBanana() { System.out.println("卖香蕉"); } } ********************************************************************* public class AppleCommand implements Command { private Peddle peddle; public AppleCommand(Peddle peddle) { this.peddle = peddle; } public Peddle getPeddle() { return peddle; } public void setPeddle(Peddle peddle) { this.peddle = peddle; } @Override public void sail() { peddle.sailAppl(); } } ********************************************************************* public class BananaCommand implements Command { protected Peddle peddle; public BananaCommand(Peddle peddle) { this.peddle = peddle; } @Override public void sail() { peddle.sailBanana(); } } ********************************************************************* public class Waiter { //一系列命令类 private List<Command> commands = new ArrayList<>(); public void setOrder(Command command) { commands.add(command); } public void removeOrder(Command command) { commands.remove(command); } public void sail() { for(Command c:commands) { c.sail(); } } } ********************************************************************* public static void main(String[] args) { Peddle peddle = new Peddle(); //方式一 // peddle.sailAppl(); // peddle.sailBanana(); //方式二 Command appleCom = new AppleCommand(peddle); // appleCom.sail(); // // System.out.println("******************"); Command bananaCom = new BananaCommand(peddle); // bananaCom.sail(); //方式三,使用Invoker调用command然后通过command调用上架peddle的方法 Waiter waiter = new Waiter(); waiter.setOrder(appleCom); waiter.setOrder(bananaCom); waiter.sail(); System.out.println("*****************"); waiter.removeOrder(bananaCom); waiter.sail(); } ********************************************************************* 输出结果: 卖苹果 卖香蕉 ***************** 卖苹果
实例代码四:这个与第三个实例差不多,只是waiter类中只有一个command,而实例三种有command的集合,可以处理多个 command命令,相对来说还可以添加和删除command
********************************************************************* /** * 一个对象调用灵位一个对象,一般情况下的调用过程是:创建目标对象实例,设置调用参数,调用目标对象方法 * * 但是有些情况下有必要使用一个专门的类对这种调用过程加以封装,我们把这种称为Command类 * * 整个过程调用比较繁琐,或者存在多处调用,这时候使用Command类对该调用加以封装,便于功能再利用 * * 调用前后需要对调用参数进行某些处理 * * 调用前后需要进行某些额外的处理,比如日志,缓存,记录历史等操作。 */ public interface Command { public void sail(); } ********************************************************************* /** * 商贩卖水果 */ public class Peddle { public void sailAppl() { System.out.println("卖苹果"); } public void sailBanana() { System.out.println("卖香蕉"); } } ********************************************************************* public class AppleCommand implements Command { private Peddle peddle; public AppleCommand(Peddle peddle) { this.peddle = peddle; } public Peddle getPeddle() { return peddle; } public void setPeddle(Peddle peddle) { this.peddle = peddle; } @Override public void sail() { peddle.sailAppl(); } } ********************************************************************* public class BananaCommand implements Command { protected Peddle peddle; public BananaCommand(Peddle peddle) { this.peddle = peddle; } @Override public void sail() { peddle.sailBanana(); } } ********************************************************************* public class Waiter { private Command command; public Waiter() { } public Command getCommand() { return command; } public void setCommand(Command command) { this.command = command; } public Waiter(Command command) { this.command = command; } public void action() { command.sail(); } } ********************************************************************* public class MainClass { public static void main(String[] args) { Peddle peddle = new Peddle(); //方式一 // peddle.sailAppl(); // peddle.sailBanana(); //方式二 Command appleCom = new AppleCommand(peddle); // appleCom.sail(); // // System.out.println("******************"); Command bananaCom = new BananaCommand(peddle); // bananaCom.sail(); //方式三,使用Invoker调用command然后通过command调用上架peddle的方法 Waiter waiter = new Waiter(); waiter.setCommand(appleCom); waiter.action(); System.out.println("**************"); waiter.setCommand(bananaCom); waiter.action(); } } ************************************************ 测试结果: 卖苹果 ************** 卖香蕉