设计模式:Command--命令模式

命令模式

 

命令模式很好理解,举个例子,司令员下令让士兵去干件事情,从整个事情的角度来考虑,司令员的作用是,发出口令,口令经过传递,传到了士兵耳朵里,士兵去执行。这个过程好在,三者相互解耦,任何一方都不用去依赖其他人,只需要做好自己的事儿就行,司令员要的是结果,不会去关注到底士兵是怎么实现的。我们看看关系图:

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();
    }
}

************************************************
测试结果:
卖苹果
**************
卖香蕉

 

 命令模式三个角色,发布命令者,命令角色,执行命令角色

抽象命令角色Command

public interface Command {
    void execute();
    void undo();
}

实际命令角色:灯光开,灯光闭,不操作

// 不操作
public class LightNoCommand implements Command{
    @Override
    public void execute() {

    }

    @Override
    public void undo() {

    }
}
// 灯光关闭命令
public class LightOffCommand implements Command{

    private LightReceiver lightReceiver;

    public LightOffCommand(LightReceiver lightReceiver) {
        this.lightReceiver = lightReceiver;
    }

    @Override
    public void execute() {
        lightReceiver.off();
    }

    @Override
    public void undo() {
        lightReceiver.on();
    }
}
// 灯光打开
public class LightOnCommand implements Command{
    private LightReceiver lightReceiver;

    public LightOnCommand(LightReceiver lightReceiver) {
        this.lightReceiver = lightReceiver;
    }

    @Override
    public void execute() {
        lightReceiver.on();
    }

    @Override
    public void undo() {
        lightReceiver.off();
    }
}

命令执行者角色LightReceiver

public class LightReceiver {
    public void on() {
        System.out.println("开灯");
    }

    public void off() {
        System.out.println("关灯");
    }
}

执行console

public static void main(String[] args) {
        //命令模式 三个角色 发号命令角色 执行命令角色  命令本身角色

        RemoteController controller = new RemoteController();
        LightReceiver lightReceiver = new LightReceiver();
        LightOnCommand lightOnCommand = new LightOnCommand(lightReceiver);
        LightOffCommand lightOffCommand = new LightOffCommand(lightReceiver);
        controller.setCommand(1, lightOnCommand, lightOffCommand);
        // 按下启动按钮
        controller.onButtonWasPushed(1);
        // 按下关闭按钮
        controller.offButtonWasPushed(1);
        // 按下撤销按钮
        controller.undoButton();

        System.out.println("--------------");
        TvReceiver tvReceiver = new TvReceiver();
        TvOffCommand tvOffCommand = new TvOffCommand(tvReceiver);
        TvOnCommand tvOnCommand = new TvOnCommand(tvReceiver);
        controller.setCommand(0, tvOnCommand, tvOffCommand);
        // 按下启动按钮
        controller.onButtonWasPushed(0);
        // 按下关闭按钮
        controller.offButtonWasPushed(0);
        // 按下撤销按钮
        controller.undoButton();
    }
}
// console
开灯
关灯
开灯
--------------
电视打开了
电视关闭了
电视打开了

其他命令可以继续实现Command接口

// 电视机不操作
public class TvNoCommand implements Command{
    @Override
    public void execute() {

    }

    @Override
    public void undo() {

    }
}
// 电视机关闭
public class TvOffCommand implements Command{

    private TvReceiver tvReceiver;

    public TvOffCommand(TvReceiver tvReceiver) {
        this.tvReceiver = tvReceiver;
    }

    @Override
    public void execute() {
        tvReceiver.off();
    }

    @Override
    public void undo() {
        tvReceiver.on();
    }
}
// 电视机打开
public class TvOnCommand implements Command{
    private TvReceiver tvReceiver;

    public TvOnCommand(TvReceiver tvReceiver) {
        this.tvReceiver = tvReceiver;
    }

    @Override
    public void execute() {
        tvReceiver.on();
    }

    @Override
    public void undo() {
        tvReceiver.off();
    }
}

 电视机命令接收执行者

public class TvReceiver {

    public void on() {
        System.out.println("电视打开了");
    }
    public void off() {
        System.out.println("电视关闭了");
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值