zoukankan      html  css  js  c++  java
  • 命令模式(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();
    }
    
  • 相关阅读:
    [转]WPF 4 媒体播放器(MediaElement)
    WPF简单的文件资源管理
    shell脚本自动化部署
    Linux知识
    单例模式及其四种实现方式
    支付宝对接步骤 (app)
    《异类》读书摘要(上)
    Linux初级指令
    项目构建基础统一结果,统一异常,统一日志
    git看这一篇就够用了
  • 原文地址:https://www.cnblogs.com/fomin/p/9987626.html
Copyright © 2011-2022 走看看