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();
    }
    
  • 相关阅读:
    Thinking in Java Reading Note(9.接口)
    Thinking in java Reading Note(8.多态)
    Thinking in Java Reading Note(7.复用类)
    SQL必知必会
    Thinking in Java Reading Note(5.初始化与清理)
    Thinking in Java Reading Note(2.一切都是对象)
    鸟哥的Linux私房菜笔记(1.基础)
    Thinking in Java Reading Note(1.对象导论)
    CoreJava2 Reading Note(2:I/O)
    CoreJava2 Reading Note(1:Stream)
  • 原文地址:https://www.cnblogs.com/fomin/p/9987626.html
Copyright © 2011-2022 走看看