zoukankan      html  css  js  c++  java
  • [design pattern](8) Command

    前言

    在前面的章节中,我们介绍了单例模式,它是创建型模式的一员。今天我们来介绍一下命令模式,它是行为型模式的一员。

    思考题

    首先,让我们来思考下面的问题:

    话说有一家遥控器公司,他想制作一款很牛逼的遥控器。这个遥控器可以控制家里所有的电器,为了简单一点,假设所有的用户家里只有电视机和电灯两种电器。那么如果是你,你会怎么实现这个遥控器呢?

     由于电视机和电灯是两个不同的厂商生产的产品,所以他们的打开方式是不一样的。首先让我们来看一看这两个类的定义:

    Television.java:

    public class Television {
        public void open() {
            System.out.println("打开电视");
        }
    
        public void close() {
            System.out.println("关闭电视");
        }
    }

    ElectricLight.java:

    public class ElectricLight {
        public void on() {
            System.out.println("打开电灯");
        }
    
        public void off() {
            System.out.println("关闭电灯");
        }
    }

    让我们来看下下面的设计:

    RemoteControl.java:

    public class RemoteControl {
        private String product;
    
        public void setProduct(String product) {
            this.product = product;
        }
    
        public void execute() {
            switch (product) {
                case "Television":
                    new Television().open();
                    break;
                case "ElectricLight":
                    new ElectricLight().on();
                    break;
                default:
            }
        }
    }

    这个遥控器太棒了,我可以用它来控制家里的电视机和电灯,再也不用到处翻找遥控器了。要是它还可以控制洗衣机那就更棒了。那么如果再在遥控器里添加一个洗衣机需要怎么做,哦,太糟糕了,我还需要把遥控器拆开,然后把洗衣机的命令添加进去,好痛苦有么有,那么有么有一种设计可以不对遥控器进行更改,就可以添加其他的家电呢。这个时候命令模式就可以发挥它的作用了。

    命令模式

    定义:将请求封装成对象,从而可以使用不同的请求将客户参数化,使得请求发送者和请求接受者之间互相隔离。

    类图:

    上面涉及到的角色有4个:

    • 抽象命令:将命令封装成一个接口,每个接收者都需要实现一个相应的命令接口。
    • 具体命令:实现了抽象命令类的方法,并且调用了具体接受者的方法。
    • 请求接受者:具体要执行操作的类。
    • 请求发送者:将命令对象传递给具体的接受者,执行相应的操作。

    思考题实现

    首先,定义一个抽象命令类:

    Command.java:

    public interface Command {
        void execute();
    }

    然后,实现抽象命令类:

    TelevisionCommand.java:

    public class TelevisionCommand implements Command {
        private Television television = new Television();
    
        @Override
        public void execute() {
            television.open();
        }
    }

    ElectricLightCommand.java:

    public class ElectricLightCommand implements Command {
        private ElectricLight electricLight = new ElectricLight();
    
        @Override
        public void execute() {
            electricLight.on();
        }
    }

    然后,实现一个遥控器:

    RemoteControl.java:

    public class RemoteControl {
        private Command command;
    
        public void execute() {
            command.execute();
        }
    
        public void initCommand(Command command) {
            this.command = command;
        }
    }

    测试类:

    Custom.java:

    public class Custom {
        public static void main(String ...args) {
            RemoteControl remoteControl = new RemoteControl();
    
        remoteControl.initCommand(new TelevisionCommand());
        remoteControl.execute();
    
        remoteControl.initCommand(new ElectricLightCommand());
        remoteControl.execute();
        }
    }
  • 相关阅读:
    2020.4.21 考试T1 HDU 5729
    BZOJ 4198: [Noi2015]荷马史诗
    BZOJ 1052: [HAOI2007]覆盖问题
    BZOJ 1087: [SCOI2005]互不侵犯King
    BZOJ 4466 线性函数
    Linux如何挂载U盘
    集中式日志分析平台
    ELK5.2+kafka+zookeeper+filebeat集群部署
    浅析ES的_source、_all、store、index
    IndexOf、LastIndexOf、Substring的用法
  • 原文地址:https://www.cnblogs.com/cafebabe-yun/p/11477258.html
Copyright © 2011-2022 走看看