命令模式

孤街醉人 提交于 2020-03-18 00:47:20

某厂面试归来,发现自己落伍了!>>>

            命令模式是对命令的封装, 每一个命令都是一个操作,请求的一方发出请求要求执行一个操作, 接受的一方收到请求, 并
    执行操作。命令模式解耦了请求方和接收方, 请求方只需请求执行命令, 不用关心命令是怎样被接收,怎样被操作以及是否被执行等
    特征:解耦命令请求与处理;属于行为型模式

使用场景:
    1、现实语义中具备"命令"的操作(命令菜单,shell命令)
     2、请求调用者和请求接受者需要解耦, 使得调用者和接受者不直接交互
     3、需要抽象出等待执行的行为, 比如撤销(Undo)操作和恢复(Redo)等操作
     4、需要支持命令宏(命令组合操作)

public interface ICommand {
    /**
     * 执行
     */
    void execute();
}
public class Invoker {

    private ICommand mCmd;

    public Invoker(ICommand mCmd) {
        this.mCmd = mCmd;
    }

    public void action(){
        this.mCmd.execute();
    }
}
public class Receiver {

    public void action(){
        System.out.println("执行具体操作");
    }
}
public class ConcreteCommand implements ICommand{

    private Receiver receiver = new Receiver();
    @Override
    public void execute() {
        receiver.action();
    }
}
public static void main(String[] args) {
    ICommand command = new ConcreteCommand();
    Invoker invoker = new Invoker(command);
    invoker.action();
}

=======================================================================================

public class Player {

   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 PauseAction implements IAction {

    private Player player;

    public PauseAction(Player player) {
        this.player = player;
    }

    @Override
    public void execute() {
        player.pause();
    }
}
public class StopAction implements IAction {

    private Player player;

    public StopAction(Player player) {
        this.player = player;
    }

    @Override
    public void execute() {
        this.player.stop();
    }
}
public class SpeedAction implements IAction {

    private Player player;

    public SpeedAction(Player player) {
        this.player = player;
    }

    @Override
    public void execute() {
        this.player.speed();
    }
}
public class PlayAction implements IAction {
    private Player player;

    public PlayAction(Player player) {
        this.player = player;
    }

    @Override
    public void execute() {
        this.player.play();
    }
}
public class Controller {

  private List<IAction> actions = new ArrayList<>();

  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 static void main(String[] args) {

    Player player = new Player();
    Controller controller = new Controller();
    controller.execute(new PauseAction(player));

    controller.addAction(new PauseAction(player));
    controller.addAction(new PlayAction(player));
    controller.addAction(new StopAction(player));
    controller.addAction(new SpeedAction(player));

    controller.executes();

}

源码中的实现:    Runnable接口; Junit包下面的Test接口

优点:
    1、通过引入中间件(抽象接口), 解耦了命令请求与实现
    2、扩展性良好, 可以很容易地增加新命令
    3、支持组合命令, 支持命令队列
    4、可以在现有命令的基础上, 增加额外功能(日志记录等, 结合装饰器模式更好)
缺点:
    1、具体命令类可能过多
    2、增加了程序的复杂度, 理解更加困难
 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!