zoukankan      html  css  js  c++  java
  • 设计模式学习总结(十九)--命令模式

    定义

    将请求封装成对象,以便使用不同的请求、日志、队列等来参数化其他对象。命令模式也支持撤销操作。

    角色

    • Command:定义命令的统一接口

    • ConcreteCommand:Command接口的实现者,用来执行具体的命令,某些情况下可以直接用来充当Receiver。

    • Receiver:命令的实际执行者

    • Invoker:命令的请求者,是命令模式中最重要的角色。这个角色用来对各个命令进行控制。

    命令模式的本质就在于将命令进行封装,将发出命令的责任和执行命令的责任分开,使发送者只需要知道如何发送命令即可,不需要了解命令是如何实现的,甚至命令执行是否成功都不需要理会。同时命令模式使得请求也变成了一个对象,它像其他对象一样可以被存储和传递。

    优缺点

    优点:

    • 降低了系统耦合度

    • 新的命令可以很容易添加到系统中去。

    缺点:

    • 使用命令模式可能会导致某些系统有过多的具体命令类。

    实例

    以遥控器操控电视机为例。

    电视机:

    /**
     * 电视机
     */
    public class Television {
    
        public void open() {
            System.out.println("打开电视机......");
        }
    
        public void close() {
            System.out.println("关闭电视机......");
        }
    
        public void changeChannel() {
    
            System.out.println("切换电视频道......");
        }
    }
    

    命令接口

    /**
     * 命令接口,为所有的命令声明一个接口。所有的命令都应该实现它
     */
    public interface Command {
        void execute();
    }
    
    

    遥控器:

    /**
     * 遥控器
     */
    public class Controller {
        private Command openTVCommand;
        private Command closeTVCommand;
        private Command changeChannelCommand;
    
        public Controller(Command openTvCommand,Command closeTvCommand,Command changeChannelCommand){
            this.openTVCommand = openTvCommand;
            this.closeTVCommand = closeTvCommand;
            this.changeChannelCommand = changeChannelCommand;
        }
    
        /**
         * 打开电视剧
         */
        public void open(){
            openTVCommand.execute();
        }
    
        /**
         * 关闭电视机
         */
        public void close(){
            closeTVCommand.execute();
        }
    
        /**
         * 换频道
         */
        public void change(){
            changeChannelCommand.execute();
        }
    }
    

    具体按钮对象:

    /**
     * 遥控器开机按钮
     */
    public class OpenTvCommand implements Command {
        private Television tv;
    
        public OpenTvCommand() {
            tv = new Television();
        }
    
    
        @Override
        public void execute() {
            tv.open();
        }
    }
    
    /**
     * 遥控器调频按钮
     */
    public class ChangeChannelCommand implements Command {
        private Television tv;
    
        public ChangeChannelCommand() {
            tv = new Television();
        }
        @Override
        public void execute() {
            tv.changeChannel();
        }
    }
    
    
    /**
     * 遥控器关机按钮
     */
    public class CloseTvCommand implements Command {
    
        private Television tv;
    
        public CloseTvCommand() {
            tv = new Television();
        }
        @Override
        public void execute() {
            tv.close();
        }
    }
    

    测试:

    public static void main(String[] args) {
        Command openCommand, closeCommand, changeCommand;
    
        openCommand = new OpenTvCommand();
        closeCommand = new CloseTvCommand();
        changeCommand = new ChangeChannelCommand();
    
        Controller control = new Controller(openCommand, closeCommand, changeCommand);
        // 打开电视机
        control.open();
        // 换频道
        control.change();
        // 关闭电视机
        control.close();
    }
    

    控制台输出:

    打开电视机......
    切换电视频道......
    关闭电视机......
    
  • 相关阅读:
    React Native 架构演进
    React Native 架构一览
    React Native 在 Airbnb 的起起落落
    React Native简史
    图解云服务模型的演进
    伯克利研究员们眼中的Cloud Computing
    彻底理解 IaaS、PaaS、SaaS
    JS更随机的随机数
    JS自动化
    fingerprint2 计算浏览器指纹分析
  • 原文地址:https://www.cnblogs.com/markLogZhu/p/11582685.html
Copyright © 2011-2022 走看看