命令模式(Command)

1、概念

命令模式将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化;对请求排队或记录请求日志,以及支持可取消的操作,属于行为型模式的一种。
图片

2、模式结构

  • Command类:是一个抽象类,类中对需要执行的命令进行声明,一般来说要对外公布一个execute方法用来执行命令。
  • ConcreteCommand类:Command类的实现类,对抽象类中声明的方法进行实现
  • Invoker类:调用者,负责调用命令。
  • Receiver类:接收者,负责接收命令并且执行命令

3、使用场景

  • 需要将请求调用者和接收者解耦,使得两者不直接交互
  • 要在不同的时间指定请求、将请求排队和执行请求
  • 需要支持命令的撤销(Undo)操作和恢复(Redo)操作
  • 需要将一组操作组合在一起,即支持宏命令

4、优缺点

优点:

  • 降低系统的耦合度,使得对象类完全解耦
  • 将行为的具体实现封装起来,客户端无需关心行为的具体实现
  • 为多种行为提供统一的调用入口,便于程序对行为的管理和控制
  • 可以组合成复合命令(宏命令),使操作系统更简单和功能强大

缺点:

  • 使用命令模式,不论命令简单还是复杂,都需要写一个命令类来封装,滥用命令模式会导致系统出现过多的具体命令类

5、实例

定义ICommand 类,只有execute方法

public interface ICommand {
    void execute();
}

定义MusicPlayer类,负责接收命令并且执行命令

public class MusicPlayer {

    public void play() {

    }

    public void skip() {

    }

    public void stop() {

    }
}

具体命令类PlayCommand

public class PlayCommand implements ICommand {

    private MusicPlayer player;

    public PlayCommand(MusicPlayer player) {
        this.player = player;
    }

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

具体命令类SkipCommand

public class SkipCommand implements ICommand {
    private MusicPlayer player;

    public SkipCommand(MusicPlayer player) {
        this.player = player;
    }

    @Override
    public void execute() {
        player.skip();
    }
}

具体命令类StopCommand

public class StopCommand implements ICommand {
    private MusicPlayer player;

    public StopCommand(MusicPlayer player) {
        this.player = player;
    }

    @Override
    public void execute() {
        player.stop();
    }
}

定义MusicInvoker 类,负责调用命令

public class MusicInvoker {
    private ICommand playCommand;
    private ICommand skipCommand;
    private ICommand stopCommand;

    public void setPlayCommand(ICommand playCommand) {
        this.playCommand = playCommand;
    }

    public void setSkipCommand(ICommand skipCommand) {
        this.skipCommand = skipCommand;
    }

    public void setStopCommand(ICommand stopCommand) {
        this.stopCommand = stopCommand;
    }

    public void play() {
        playCommand.execute();
    }

    public void skip() {
        skipCommand.execute();
    }

    public void stop() {
        stopCommand.execute();
    }
}

客户端执行实例

public static void main(String[] args) {
    // 创建 Receiver(接收者)
    MusicPlayer musicPlayer = new MusicPlayer();
    // ICommand(抽象命令类)
    ICommand playCommand = new PlayCommand(musicPlayer);
    ICommand skipCommand = new SkipCommand(musicPlayer);
    ICommand stopCommand = new StopCommand(musicPlayer);
    // 创建 Invoker(调用者)
    MusicInvoker invoker = new MusicInvoker();
    invoker.setPlayCommand(playCommand);
    invoker.setSkipCommand(skipCommand);
    invoker.setStopCommand(stopCommand);
    // 测试
    invoker.play();
    invoker.skip();
    invoker.stop();
    invoker.play();
    invoker.stop();
}

组合命令,形成宏命令,定义IMacroCommand类

public interface IMacroCommand extends ICommand {

    void add(ICommand command);

    void remove(ICommand command);
}

定义MacroMusicCommand 类

public class MacroMusicCommand implements IMacroCommand {

    private static final List<ICommand> commands = new ArrayList<>();

    @Override
    public void add(ICommand command) {
        commands.add(command);
    }

    @Override
    public void remove(ICommand command) {
        commands.remove(command);
    }

    @RequiresApi(api = Build.VERSION_CODES.N)
    @Override
    public void execute() {
        commands.forEach(ICommand::execute);
    }
}

客户端调用

public static void main(String[] args) {
    // 创建 Receiver(接收者)
    MusicPlayer musicPlayer = new MusicPlayer();
    // ICommand(抽象命令类)
    ICommand playCommand = new PlayCommand(musicPlayer);
    ICommand skipCommand = new SkipCommand(musicPlayer);
    ICommand stopCommand = new StopCommand(musicPlayer);
    // 创建 Invoker(调用者)
    MacroMusicCommand invoker = new MacroMusicCommand();
    invoker.add(playCommand);
    invoker.add(skipCommand);
    invoker.add(stopCommand);
    // 测试
    invoker.execute();
}
posted @ 2018-11-20 10:54  fomin  阅读(200)  评论(0编辑  收藏  举报